Bu sayfada Bazel'in iki görünürlük sistemi ele alınmaktadır: hedef görünürlük ve yükleme görünürlüğü.
Her iki görünürlük türü de diğer geliştiricilerin, kitaplığınızın herkese açık API'si ile uygulama ayrıntılarını ayırt etmesine ve çalışma alanınız büyüdükçe yapının uygulanmasına yardımcı olur. Ayrıca, herkese açık bir API'nin desteğini sonlandırırken mevcut kullanıcılara izin vermek ve yeni kullanıcıları reddetmek için de görünürlük özelliğini kullanabilirsiniz.
Hedef görünürlük
Hedef görünürlüğü, hedefinize bağlı olabilecek kullanıcıları (yani deps
gibi bir özellik içinde hedefinizin etiketini kullanabilecek kullanıcıları) kontrol eder.
Aynı paketteyse veya A
, B
'nin paketine görünürlük sağlıyorsa bir A
hedefi, B
hedefine görünür. Bu nedenle, erişime izin verilip verilmeyeceğine karar vermek için paketler ayrıntı düzeyi birimidir. B
, A
öğesine bağımlıysa ancak A
, B
tarafından görülemiyorsa analiz sırasında B
derlemesi girişimi başarısız olur.
Bir pakete görünürlük verilmesinin, alt paketlerinin de görünürlük kazanmasını sağlamadığını unutmayın. Paket ve alt paketler hakkında daha fazla bilgi için Kavramlar ve terminoloji bölümüne bakın.
Prototipleme için --check_visibility=false
işaretini ayarlayarak hedef görünürlüğü yaptırımını devre dışı bırakabilirsiniz. Gönderilen kodda üretim kullanımı için bu işlem yapılmamalıdır.
Görünürlüğü kontrol etmenin birincil yolu, kural hedeflerindeki visibility
özelliğini kullanmaktır. Bu bölümde, bu özelliğin biçimi ve bir hedefin görünürlüğünün nasıl belirleneceği açıklanmaktadır.
Görünürlük özellikleri
Tüm kural hedeflerinde, etiketlerin listesini alan bir visibility
özelliği bulunur. Her etiket aşağıdaki biçimlerden birine sahiptir. Son form hariç, bunlar gerçek bir hedefe karşılık gelmeyen söz dizimi yer tutucularıdır.
"//visibility:public"
: Tüm paketlere erişim izni verir. (Başka bir spesifikasyonla birleştirilemez.)"//visibility:private"
: Ek erişim izni vermez. Yalnızca bu paketteki hedefler bu hedefi kullanabilir. (Başka bir spesifikasyonla birleştirilemez.)"//foo/bar:__pkg__"
://foo/bar
'a erişim izni verir (ancak alt paketlerine erişim vermez)."//foo/bar:__subpackages__"
://foo/bar
ürününe ve tüm doğrudan ve dolaylı alt paketlerine erişim izni verir."//some_pkg:my_package_group"
: Belirtilenpackage_group
kapsamındaki tüm paketlere erişim izni verir.- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda
"//foo/bar:__pkg__"
ve"//foo/bar:__subpackages__"
formları sırasıyla"//foo/bar"
ve"//foo/bar/..."
ile değiştirilir. Benzer şekilde,"//visibility:public"
ve"//visibility:private"
,"public"
ve"private"
'tır.
- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda
Örneğin, //some/package:mytarget
'ün visibility
özelliği [":__subpackages__", "//tests:__pkg__"]
olarak ayarlanmışsa //some/package/...
kaynak ağacının parçası olan tüm hedeflerin yanı sıra //tests/BUILD
'te tanımlanan hedefler tarafından kullanılabilir ancak //tests/integration/BUILD
'te tanımlanan hedefler tarafından kullanılamaz.
En iyi uygulama: Birden fazla hedefi aynı paket grubuna görünür hale getirmek için her hedefin visibility
özelliğinde listeyi tekrarlamak yerine bir package_group
kullanın. Bu, okunabilirliği artırır ve listelerin senkronize edilmesini önler.
Kural hedefi görünürlüğü
Kural hedefinin görünürlüğü:
Ayarlanmışsa
visibility
özelliğinin değeri, aksi takdirdeHedefin
BUILD
dosyasındakipackage
ifadesinindefault_visibility
bağımsız değişkeninin değeri (böyle bir beyan varsa)//visibility:private
.
En iyi uygulama: default_visibility
'yi herkese açık olarak ayarlamamaya çalışın. Bu yöntem, prototip oluşturma veya küçük kod tabanlarında kullanışlı olabilir ancak kod tabanı büyüdükçe yanlışlıkla herkese açık hedefler oluşturma riski artar. Paketin herkese açık arayüzünün bir parçası olan hedeflerin açıkça belirtilmesi daha iyidir.
Örnek
Dosya //frobber/bin/BUILD
:
# This target is visible to everyone
cc_binary(
name = "executable",
visibility = ["//visibility:public"],
deps = [":library"],
)
# This target is visible only to targets declared in the same package
cc_library(
name = "library",
# No visibility -- defaults to private since no
# package(default_visibility = ...) was used.
)
# This target is visible to targets in package //object and //noun
cc_library(
name = "subject",
visibility = [
"//noun:__pkg__",
"//object:__pkg__",
],
)
# See package group "//frobber:friends" (below) for who can
# access this target.
cc_library(
name = "thingy",
visibility = ["//frobber:friends"],
)
Dosya //frobber/BUILD
:
# This is the package group declaration to which target
# //frobber/bin:thingy refers.
#
# Our friends are packages //frobber, //fribber and any
# subpackage of //fribber.
package_group(
name = "friends",
packages = [
"//fribber/...",
"//frobber",
],
)
Oluşturulan dosya hedefi görünürlüğü
Oluşturulan dosya hedefi, onu oluşturan kural hedefiyle aynı görünürlüğe sahiptir.
Kaynak dosya hedef görünürlüğü
exports_files
işlevini çağırarak bir kaynak dosya hedefinin görünürlüğünü açıkça ayarlayabilirsiniz. exports_files
işlevine visibility
bağımsız değişkeni iletilmediğinde görünürlük herkese açık olur.
exports_files
, oluşturulan bir dosyanın görünürlüğünü geçersiz kılmak için kullanılamaz.
exports_files
çağrısında görünmeyen kaynak dosya hedefleri için görünürlük, --incompatible_no_implicit_file_export
işaretinin değerine bağlıdır:
İşaretçi ayarlanmışsa görünürlük gizlidir.
Aksi takdirde, eski davranış geçerlidir: Görünürlük,
BUILD
dosyasınındefault_visibility
değeriyle aynıdır veya varsayılan bir görünürlük belirtilmediyse gizlidir.
Eski davranışa güvenmekten kaçının. Bir kaynak dosya hedefinin gizli olmayan görünürlüğe ihtiyacı olduğunda her zaman bir exports_files
beyanı yazın.
En iyi uygulama: Mümkün olduğunda kaynak dosya yerine kural hedefi göstermeyi tercih edin. Örneğin, .java
dosyasında exports_files
yöntemini çağırmak yerine dosyayı gizli olmayan bir java_library
hedefine sarmalayın. Kural hedefleri genellikle yalnızca aynı pakette bulunan kaynak dosyalara doğrudan referans vermelidir.
Örnek
//frobber/data/BUILD
dosyası:
exports_files(["readme.txt"])
//frobber/bin/BUILD
dosyası:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
Yapılandırma ayarı görünürlüğü
Bazel geçmişte, select()
anahtarlarında referans verilen config_setting
hedefleri için görünürlüğü zorunlu kılmamıştır. Bu eski davranışı kaldırmak için iki işaret vardır:
--incompatible_enforce_config_setting_visibility
bu hedefler için görüntülenebilirlik kontrolünü etkinleştirir. Taşıma işlemine yardımcı olmak için,visibility
belirtmeyen tümconfig_setting
'lerin herkese açık olarak kabul edilmesine de (paket düzeyindekidefault_visibility
'den bağımsız olarak) neden olur.--incompatible_config_setting_private_default_visibility
,visibility
belirtmeyenconfig_setting
'ların paketindefault_visibility
'ine uymasına ve diğer tüm kural hedeflerinde olduğu gibi gizli görünürlükte geriye dönük bir işlem yapmasına neden olur.--incompatible_enforce_config_setting_visibility
ayarlanmamışsa işlem yapılmaz.
Eski davranışı kullanmaktan kaçının. Mevcut paketin dışında kullanılması amaçlanan tüm config_setting
öğelerinin açık bir visibility
değeri olmalıdır. Aksi takdirde, pakette uygun bir default_visibility
belirtilmemişse config_setting
öğesi geçersiz olur.
Paket grubu hedef görünürlüğü
package_group
hedeflerinin visibility
özelliği yok. Bu bilgiler her zaman herkese açıktır.
Örtük bağımlılıkların görünürlüğü
Bazı kurallarda örtülü bağımlılıklar bulunur. Bu bağımlılıklar, BUILD
dosyasında belirtilmez ancak söz konusu kuralın her örneğine özgüdür. Örneğin, bir cc_library
kuralı, kural hedeflerinin her birinden C++ derleyiciyi temsil eden yürütülebilir bir hedefe örtülü bağımlılık oluşturabilir.
Şu anda, görünürlük amacıyla bu gizli bağımlılıklar diğer tüm bağımlılıklarla aynı şekilde ele alınır. Bu, bağımlı olan hedefin (C++ derleyicimiz gibi) kuralın her örneğine görünür olması gerektiği anlamına gelir. Uygulamada bu, genellikle hedefin herkese açık bir görünürlüğe sahip olması gerektiği anlamına gelir.
Bu davranışı --incompatible_visibility_private_attributes_at_definition
olarak ayarlayarak değiştirebilirsiniz. Etkinleştirildiğinde, söz konusu hedefin yalnızca kendisini dolaylı bağımlılık olarak belirten kural tarafından görünür olması gerekir. Yani, kuralın tanımlandığı .bzl
dosyasını içeren paket tarafından görülebilmelidir. Örneğimizde, C++ derleyicisi, cc_library
kuralı tanımı ile aynı pakette bulunduğu sürece özel olabilir.
Yük görünürlüğü
Yükleme görünürlüğü, bir .bzl
dosyasının diğer BUILD
veya .bzl
dosyalarından yüklenip yüklenemeyeceğini kontrol eder.
Hedef görünürlüğü, hedefler tarafından kapsüllenen kaynak kodu koruduğu gibi, yükleme görünürlüğü de .bzl
dosyaları tarafından kapsüllenen derleme mantığını korur. Örneğin, bir BUILD
dosyası yazarı, bazı tekrarlanan hedef tanımlarını .bzl
dosyasındaki bir makroya dahil etmek isteyebilir. Yükleme görünürlüğünün koruması olmadan, makrolarının aynı çalışma alanındaki diğer ortak çalışanlar tarafından yeniden kullanıldığını görebilirler. Bu durumda, makroda yapılan değişiklikler diğer ekiplerin derlemelerini bozar.
.bzl
dosyalarının karşılık gelen bir kaynak dosya hedefi olabileceğini veya olmayabileceğini unutmayın.
Bu durumda, yük görünürlüğü ile hedef görünürlüğün çakıştığının garantisi yoktur. Yani aynı BUILD
dosyası .bzl
dosyasını yükleyebilir ancak filegroup
dosyasının srcs
bölümünde listeleyebilir veya bunun tam tersini yapabilir. Bu durum, .bzl
dosyalarını kaynak kodu olarak kullanmak isteyen kurallar (ör. doküman oluşturma veya test etme) için bazen sorunlara yol açabilir.
Prototipleme için --check_bzl_visibility=false
değerini ayarlayarak yükleme görünürlüğü yaptırımını devre dışı bırakabilirsiniz. --check_visibility=false
ile olduğu gibi, gönderilen kod için bu işlem yapılmamalıdır.
Yükleme görünürlüğü, Bazel 6.0'dan itibaren kullanılabilmektedir.
Yük görünürlüğünü belirtme
Bir .bzl
dosyasının yükleme görünürlüğünü ayarlamak için dosya içinden visibility()
işlevini çağırın.
visibility()
bağımsız değişkeni, package_group
'in packages
özelliği gibi paket özelliklerinin bir listesidir. Ancak visibility()
, negatif paket özelliklerini kabul etmez.
visibility()
çağrısı, her dosya için yalnızca bir kez, üst düzeyde (bir işlevin içinde değil) ve ideal olarak load()
ifadelerinin hemen ardından yapılmalıdır.
Hedef görünürlüğün aksine, varsayılan yükleme görünürlüğü her zaman herkese açıktır. visibility()
çağrısı yapmayan dosyalar, çalışma alanının herhangi bir yerinden her zaman yüklenebilir. Paket dışında kullanılmak üzere özel olarak tasarlanmamış tüm yeni .bzl
dosyalarının en üstüne visibility("private")
eklemek iyi bir fikirdir.
Örnek
# //mylib/internal_defs.bzl
# Available to subpackages and to mylib's tests.
visibility(["//mylib/...", "//tests/mylib/..."])
def helper(...):
...
# //mylib/rules.bzl
load(":internal_defs.bzl", "helper")
# Set visibility explicitly, even though public is the default.
# Note the [] can be omitted when there's only one entry.
visibility("public")
myrule = rule(
...
)
# //someclient/BUILD
load("//mylib:rules.bzl", "myrule") # ok
load("//mylib:internal_defs.bzl", "helper") # error
...
Görünürlük uygulamalarını yükle
Bu bölümde, yük görünürlüğü beyanlarını yönetmeyle ilgili ipuçları açıklanmaktadır.
Görünürlükleri dikkate alma
Birden fazla .bzl
dosyasının aynı görünürlüğe sahip olması gerektiğinde, bunların paket özelliklerini ortak bir listede hesaba katmak faydalı olabilir. Örneğin:
# //mylib/internal_defs.bzl
visibility("private")
clients = [
"//foo",
"//bar/baz/...",
...
]
# //mylib/feature_A.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
# //mylib/feature_B.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
Bu, çeşitli .bzl
dosyalarının görünürlükleri arasında yanlışlıkla kayma olmasını önlemeye yardımcı olur. Ayrıca, clients
listesi büyük olduğunda daha okunaklı olur.
Görünürlükleri birleştirme
Bazen bir .bzl
dosyasının, birden fazla küçük izin verilenler listesinden oluşan bir izin verilenler listesi için görünür olması gerekebilir. Bu, bir package_group
'nin includes
özelliği aracılığıyla diğer package_group
'leri dahil etmesine benzer.
Yaygın olarak kullanılan bir makronun desteğini sonlandırdığınızı varsayalım. Yalnızca mevcut kullanıcılar ve kendi ekibinizin sahip olduğu paketler tarafından görülebilmesini istiyorsunuz. Şunu yazabilirsiniz:
# //mylib/macros.bzl
load(":internal_defs.bzl", "our_packages")
load("//some_big_client:defs.bzl", "their_remaining_uses)
# List concatenation. Duplicates are fine.
visibility(our_packages + their_remaining_uses)
Paket gruplarıyla tekilleştirme
Hedef görünürlüğün aksine, yük görünürlüğünü package_group
açısından tanımlayamazsınız. Hem hedef görünürlük hem de yükleme görünürlüğü için aynı izin verilenler listesini yeniden kullanmak istiyorsanız paket spesifikasyonlarının listesini, her iki tür beyanın da referans verebileceği bir .bzl dosyasına taşımak en iyisidir. Yukarıdaki Görünürlükleri hesaba katma bölümündeki örnekten yola çıkarak şunları yazabilirsiniz:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
Bu işlem yalnızca listede negatif paket özellikleri yoksa çalışır.
Tek tek sembolleri koruma
Adı alt çizgiyle başlayan bir Starlark sembolü başka bir dosyadan yüklenemez. Bu, özel simgeler oluşturmayı kolaylaştırır ancak bu simgeleri sınırlı sayıda güvenilir dosyayla paylaşmanıza izin vermez. Diğer yandan, yük görünürlüğü, diğer paketlerin .bzl file
öğenizi görebileceklerini kontrol etmenizi sağlar ancak alt çizgisiz sembollerin yüklenmesini önlemenize izin vermez.
Daha ayrıntılı bir kontrol elde etmek için bu iki özelliği birleştirebilirsiniz.
# //mylib/internal_defs.bzl
# Can't be public, because internal_helper shouldn't be exposed to the world.
visibility("private")
# Can't be underscore-prefixed, because this is
# needed by other .bzl files in mylib.
def internal_helper(...):
...
def public_util(...):
...
# //mylib/defs.bzl
load(":internal_defs", "internal_helper", _public_util="public_util")
visibility("public")
# internal_helper, as a loaded symbol, is available for use in this file but
# can't be imported by clients who load this file.
...
# Re-export public_util from this file by assigning it to a global variable.
# We needed to import it under a different name ("_public_util") in order for
# this assignment to be legal.
public_util = _public_util
bzl- visibility derleyici hata analizi
Kullanıcının dosyası söz konusu dizinin üst klasöründe değilken kullanıcılar internal
veya private
adlı bir dizinden dosya yüklerse uyarı veren bir Buildifier lint vardır. Bu lint, yükleme görünürlüğü özelliğinden öncedir ve .bzl
dosyalarının görünürlüğü tanımladığı çalışma alanlarında gereksizdir.