Bu sayfada Bazel'in iki görünürlük sistemi ele alınmaktadır: Hedef görünürlüğü 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ıyı zorunlu kılmaya yardımcı olur. Ayrıca, herkese açık bir API'nin desteğini sonlandırırken mevcut kullanıcılara izin verip yeni kullanıcıları engellemek için de görünürlüğü kullanabilirsiniz.
Hedef görünürlüğü
Hedef görünürlüğü, hedefinizden kimlerin yararlanabileceğini (ör. deps
gibi bir özellik içinde hedefinizin etiketini kimlerin kullanabileceğini) kontrol etmenizi sağlar.
Bir hedef A
, aynı paketteyse veya A
, B
'nin paketine görünürlük veriyorsa hedef B
tarafından görülebilir. Bu nedenle, erişime izin verilip verilmeyeceğine karar verirken paketler ayrıntı birimi olarak kullanılır. B
, A
SDK'sına bağlıysa ancak A
, B
SDK'sına görünmüyorsa B
SDK'sını oluşturma girişimleri analiz sırasında başarısız olur.
Bir pakete görünürlük verilmesinin, alt paketlerine görünürlük verilmesini sağlamadığını unutmayın. Paketler ve alt paketler hakkında daha fazla bilgi için Kavramlar ve terminoloji başlıklı makaleyi inceleyin.
Prototip oluşturma için --check_visibility=false
işaretini ayarlayarak hedef görünürlüğü zorunluluğunu devre dışı bırakabilirsiniz. Bu işlem, gönderilen kodda üretim kullanımı için yapılmamalıdır.
Görünürlüğü kontrol etmenin temel 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, etiket listesi alan bir visibility
özelliği bulunur. Her etiket aşağıdaki biçimlerden birine sahiptir. Son form hariç olmak üzere bunlar, herhangi bir gerçek hedefle eşleşmeyen yalnızca söz dizimsel yer tutuculardı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
'e (ancak alt paketlerine değil) erişim izni verir."//foo/bar:__subpackages__"
://foo/bar
ve doğrudan ve dolaylı olarak tüm alt paketlerine erişim izni verir."//some_pkg:my_package_group"
: Belirtilenpackage_group
'ın parçası olan 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. Aynı şekilde,"//visibility:public"
ve"//visibility:private"
yalnızca"public"
ve"private"
'dür.
- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda,
Örneğin, //some/package:mytarget
öğesinin visibility
özelliği [":__subpackages__", "//tests:__pkg__"]
olarak ayarlanmışsa bu öğe, //some/package/...
kaynak ağacının parçası olan tüm hedefler ve //tests/BUILD
içinde tanımlanan hedefler tarafından kullanılabilir ancak //tests/integration/BUILD
içinde tanımlanan hedefler tarafından kullanılamaz.
En iyi uygulama: Aynı paket grubunun birden fazla hedefi görmesini sağlamak için listeyi her hedefin visibility
özelliğinde tekrarlamak yerine package_group
kullanın. Bu sayede okunabilirlik artar ve listelerin senkronizasyonunun bozulması önlenir.
Kural hedefi görünürlüğü
Bir kuralın hedef 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 bildirim varsa) veya//visibility:private
.
En iyi uygulama: default_visibility
değerini herkese açık olarak ayarlamaktan kaçının. 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. Hangi hedeflerin bir paketin herkese açık arayüzünün parçası olduğu konusunda açık olmak 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 dosyanın hedef 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. visibility
argümanı exports_files
'ye iletilmediğinde görünürlük herkese açık hale gelir.
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 ayarlanırsa görünürlük gizli olur.
Aksi takdirde eski davranış geçerli olur: Görünürlük,
BUILD
dosyasınındefault_visibility
görünürlüğüyle aynıdır veya varsayılan görünürlük belirtilmemişse 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 exports_files
bildirim 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
işlevini çağırmak yerine dosyayı gizli olmayan bir java_library
hedefiyle sarmalayın. Genel olarak, kural hedefleri yalnızca aynı pakette bulunan kaynak dosyalara doğrudan referans vermelidir.
Örnek
Dosya //frobber/data/BUILD
:
exports_files(["readme.txt"])
Dosya //frobber/bin/BUILD
:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
Yapılandırma ayarı görünürlüğü
Geçmişte Bazel, select()
anahtarlarında referans verilen config_setting
hedefler için görünürlüğü zorunlu kılmıyordu. Bu eski davranışı kaldırmak için iki işaret vardır:
--incompatible_enforce_config_setting_visibility
bu hedefler için görünürlük kontrolünü etkinleştirir. Taşımaya yardımcı olmak içinvisibility
belirtilmeyen tümconfig_setting
öğelerinin herkese açık olarak kabul edilmesine de neden olur (paket düzeyindekidefault_visibility
'den bağımsız olarak).--incompatible_config_setting_private_default_visibility
visibility
belirtmeyenconfig_setting
'lerin, paketindefault_visibility
'ına uymasına ve diğer tüm kural hedefleri gibi özel görünürlüğe geri dönmesine neden olur.--incompatible_enforce_config_setting_visibility
ayarlanmamışsa işlem yapılmaz.
Eski davranışa güvenmekten kaçının. Mevcut paketin dışında kullanılmak üzere tasarlanan tüm config_setting
, paket uygun bir default_visibility
belirtmiyorsa açık bir visibility
içermelidir.
Paket grubu hedef görünürlüğü
package_group
hedeflerinin visibility
özelliği yok. Bu yorumlar her zaman herkese açık olarak görünür.
Örtülü bağımlılıkların görünürlüğü
Bazı kuralların örtülü bağımlılıkları vardır. Bu bağımlılıklar, BUILD
dosyasında açıkça belirtilmeyen ancak kuralın her örneğinde bulunan bağımlılıklardır. Örneğin, bir cc_library
kuralı, kural hedeflerinin her birinden C++ derleyicisini 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 örtülü bağımlılıklar diğer bağımlılıklar gibi ele alınır. Bu, bağımlı olunan hedefin (ör. C++ derleyicimiz) kuralın her örneği tarafından görülebilir olması gerektiği anlamına gelir. Uygulamada bu genellikle hedefin herkese açık görünürlüğe sahip olması gerektiği anlamına gelir.
--incompatible_visibility_private_attributes_at_definition
değerini ayarlayarak bu davranışı değiştirebilirsiniz. Etkinleştirildiğinde, söz konusu hedef yalnızca bunu örtülü bağımlılık olarak bildiren kural tarafından görülebilir. Yani, kuralın tanımlandığı .bzl
dosyasını içeren pakette görünür olmalıdır. Örneğimizde, C++ derleyici, cc_library
kuralının tanımıyla aynı pakette bulunduğu sürece özel olabilir.
Yük görünürlüğü
Yükleme görünürlüğü, .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 kapsanan kaynak kodu koruduğu gibi yük görünürlüğü de .bzl
dosyaları tarafından kapsanan derleme mantığını korur. Örneğin, bir BUILD
dosya yazarı, bazı tekrarlayan hedef tanımlarını .bzl
dosyasındaki bir makroya dahil etmek isteyebilir. Yük görünürlüğü koruması olmadan, makroları aynı çalışma alanındaki diğer katılımcılar tarafından yeniden kullanılabilir. Bu durumda, makroda yapılan değişiklikler diğer ekiplerin derlemelerini bozabilir.
.bzl
dosyasının karşılık gelen bir kaynak dosyası hedefi olabilir veya olmayabilir.
Bu durumda, yük görünürlüğü ile hedef görünürlüğün aynı olacağı garanti edilmez. Yani, aynı BUILD
dosyası .bzl
dosyasını yükleyebilir ancak filegroup
srcs
bölümünde listelemeyebilir veya bunun tam tersi olabilir. Bu durum, bazen doküman oluşturma veya test etme gibi kaynak kodu olarak .bzl
dosyalarını kullanmak isteyen kurallar için sorunlara neden olabilir.
Prototip oluşturma için --check_bzl_visibility=false
ayarını yaparak yükleme görünürlüğü zorunluluğunu devre dışı bırakabilirsiniz. --check_visibility=false
ile aynı şekilde, bu işlem gönderilen kod için yapılmamalıdır.
Yük görünürlüğü, Bazel 6.0'dan itibaren kullanılabilir.
Yük görünürlüğünü bildirme
.bzl
dosyasının yükleme görünürlüğünü ayarlamak için dosyanın içinden visibility()
işlevini çağırın.
visibility()
işlevinin bağımsız değişkeni, package_group
öğesinin packages
özelliği gibi bir paket spesifikasyonları listesidir. Ancak visibility()
, negatif paket spesifikasyonlarını kabul etmez.
visibility()
çağrısı dosya başına yalnızca bir kez, en üst düzeyde (bir işlevin içinde değil) ve ideal olarak load()
ifadelerinden hemen sonra 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()
işlevi çağrılmayan dosyalar, çalışma alanının herhangi bir yerinden her zaman yüklenebilir. Paket dışında kullanılmak üzere tasarlanmamış yeni .bzl
dosyaları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
...
Yük görünürlüğü uygulamaları
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 faktörize etme
Birden fazla .bzl
dosyanın aynı görünürlüğe sahip olması gerektiğinde, paket özelliklerini ortak bir listede birleştirmek 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 eğrilik oluşmasını önlemeye yardımcı olur. Ayrıca, clients
listesi büyük olduğunda daha kolay okunur.
Görünürlükleri oluşturma
Bazen bir .bzl
dosyasının, birden fazla küçük izin verilenler listesinden oluşan bir izin verilenler listesi tarafından görünür olması gerekebilir. Bu, bir package_group
öğesinin includes
özelliği aracılığıyla diğer package_group
öğelerini dahil etmesine benzer.
Yaygın olarak kullanılan bir makroyu kullanımdan kaldırdığınızı varsayalım. Yalnızca mevcut kullanıcılar ve kendi ekibinizin sahip olduğu paketler tarafından görülebilmesini istiyorsanız. Şuna benzer bir mesaj 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 yinelenen öğeleri kaldırma
Hedef görünürlüğün aksine, yük görünürlüğünü bir package_group
cinsinden tanımlayamazsınız. Hem hedef görünürlüğü hem de yük görünürlüğü için aynı izin verilenler listesini yeniden kullanmak istiyorsanız paket spesifikasyonları listesini, her iki tür bildirimin de başvurabileceği bir .bzl dosyasına taşımanız 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 yalnızca listede negatif paket belirtimi yoksa çalışır.
Tek tek simgeleri koruma
Adı alt çizgiyle başlayan Starlark sembolleri başka bir dosyadan yüklenemez. Bu sayede özel semboller oluşturmak kolaylaşır ancak bu sembolleri sınırlı sayıda güvenilir dosyayla paylaşmanıza izin verilmez. Diğer taraftan, yük görünürlüğü, diğer paketlerin .bzl file
öğenizi görme şekli üzerinde kontrol sahibi olmanızı sağlar ancak alt çizgi içermeyen sembollerin yüklenmesini engellemenize izin vermez.
Neyse ki ayrıntılı kontrol 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 Buildifier lint'i
Kullanıcılar, dosyaları internal
veya private
adlı bir dizinden yüklediğinde ve dosyaları bu dizinin üst dizininin altında olmadığında uyarı veren bir Buildifier lint vardır. Bu lint, yükleme görünürlüğü özelliğinden önce oluşturulmuştur ve .bzl
dosyalarının görünürlükleri bildirdiği çalışma alanlarında gereksizdir.