Bu sayfada Bazel'ın iki görünürlük sistemi ele alınmaktadır: hedef görünürlük ve yük 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. Herkese açık bir API'yi kullanımdan kaldırırken mevcut kullanıcılara izin verirken yeni kullanıcıları reddetmek için de görünürlüğü kullanabilirsiniz.
Hedef görünürlük
Hedef görünürlüğü, hedefinize bağımlı olabilecek kişileri, yani deps
gibi bir özellik içinde hedefinizin etiketini kimlerin kullanabileceğini kontrol eder.
Bir hedef A
, aynı pakette yer alıyorlarsa veya A
, B
paketine görünürlük sağlıyorsa B
hedefine görünür. Bu nedenle, paketler erişime izin verilip verilmeyeceğine karar verirken kullanılan ayrıntı birimidir. B
, A
değerine bağımlıysa ancak A
, B
tarafından görülmezse B
oluşturma girişimleri analiz sırasında başarısız olur.
Bir pakete görünürlük izni vermenin tek başına alt paketlerine de görünürlük 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.
Prototip oluşturma için --check_visibility=false
işaretini ayarlayarak hedef görünürlüğünü 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 birincil yolu, kural hedeflerinde visibility
özelliği 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 hedefleri, etiketler listesini alan bir visibility
özelliğine sahip. Her etiket aşağıdaki biçimlerden birine sahiptir. Son biçim haricinde, bunlar yalnızca herhangi bir gerçek hedefe karşılık gelmeyen sözdizimsel yer tutuculardır.
"//visibility:public"
: Tüm paketlere erişim izni verir. (Başka herhangi bir spesifikasyonla kombine edilemez.)"//visibility:private"
: Ek erişim sağlamaz; yalnızca bu paketteki hedefler bu hedefi kullanabilir. (Başka herhangi bir spesifikasyonla birleştirilemez.)"//foo/bar:__pkg__"
://foo/bar
öğesine erişim izni verir (ancak alt paketlerine erişim izni vermez)."//foo/bar:__subpackages__"
://foo/bar
öğesine ve tüm doğrudan ve dolaylı alt paketlerine erişim izni verir."//some_pkg:my_package_group"
: Belirtilenpackage_group
öğesinin 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. Benzer şekilde,"//visibility:public"
ve"//visibility:private"
de yalnızca"public"
ve"private"
değerleridir.
- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda,
Örneğin, //some/package:mytarget
için visibility
değeri [":__subpackages__", "//tests:__pkg__"]
olarak ayarlanmışsa bu değer, //some/package/...
kaynak ağacının parçası olan herhangi bir hedefin yanı sıra //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: 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.
En iyi uygulama: Başka bir ekibin projesine görünürlük izni verirken proje gelişip yeni alt paketler eklerken gereksiz görünürlük kaybını önlemek için __pkg__
yerine __subpackages__
seçeneğini tercih edin.
Kural hedefi görünürlüğü
Bir kural hedefinin görünürlüğü:
Ayarlanmışsa öğenin
visibility
özelliğinin değeri; veya aksi takdirde,Böyle bir bildirim varsa hedefin
BUILD
dosyasındakipackage
ifadesinindefault_visibility
bağımsız değişkeni değeri veya//visibility:private
.
En iyi uygulama: default_visibility
ayarını herkese açık olarak ayarlamaktan kaçının. Bu, prototip oluşturmak için 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 hedefleri açıkça belirtmek 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 hedefinin görünürlüğü
Oluşturulan bir dosya hedefi, onu oluşturan kural hedefiyle aynı görünürlüğe sahiptir.
Kaynak dosya hedefi görünürlüğü
exports_files
yöntemini çağırarak kaynak dosya hedefinin görünürlüğünü açıkça ayarlayabilirsiniz. exports_files
öğesine hiçbir visibility
bağımsız değişkeni 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, işaretin değerine --incompatible_no_implicit_file_export
bağlıdır:
İşaret ayarlanırsa görünürlük gizli olur.
Aksi takdirde, eski davranış uygulanır: Görünürlük,
BUILD
dosyasınındefault_visibility
özelliğiyle aynıdır. Varsayılan bir görünürlük belirtilmemişse gizlidir.
Eski davranışa güvenmeyin. Kaynak dosya hedefinin gizli olmayan görünürlüğe ihtiyacı olduğunda her zaman bir exports_files
bildirimi yazın.
En iyi uygulama: Mümkün olduğunda, kaynak dosya yerine bir kural hedefi göstermeyi tercih edin. Örneğin, .java
dosyasında exports_files
çağrısı yapmak yerine dosyayı gizli olmayan bir java_library
hedefiyle sarmalayın. Genel olarak kural hedefleri, yalnızca aynı pakette bulunan kaynak dosyalarına doğrudan başvuruda bulunmalıdır.
Ö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
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ünürlük kontrolünü etkinleştirir. Bu işlem, taşımaya yardımcı olmak için aynı zamanda birvisibility
belirtmeyen tümconfig_setting
öğelerinin herkese açık olarak değerlendirilmesine neden olur (paket düzeyindekidefault_visibility
dikkate alınmaksızın).--incompatible_config_setting_private_default_visibility
,visibility
belirtmeyenconfig_setting
öğelerinin, diğer tüm kural hedeflerinde olduğu gibi, paketindefault_visibility
öğesine uymasına ve gizli görünürlüğe dönmesine neden olur.--incompatible_enforce_config_setting_visibility
ayarlanmazsa işlem yapılamaz.
Eski davranışa güvenmeyin. Mevcut paketin dışında kullanılması amaçlanan herhangi bir config_setting
, pakette zaten uygun bir default_visibility
belirtilmiyorsa açık bir visibility
öğesine sahip olmalıdır.
Paket grubu hedefi görünürlüğü
package_group
hedeflerin visibility
özelliği yok. Bunlar her zaman
her zaman herkes tarafından görülebilir.
Örtülü bağımlılıkların görünürlüğü
Bazı kuralların dolaylı bağımlılıkları vardır. Bunlar, BUILD
dosyasında yazılmayan ancak söz konusu kuralın her örneğinin doğasında 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 olan örtülü bağımlılık oluşturabilir.
Böyle bir dolaylı bağımlılığın görünürlüğü, kuralın (veya en boy özelliğinin) tanımlandığı .bzl
dosyasını içeren pakete göre kontrol edilir. Örneğimizde C++ derleyicisi, cc_library
kuralının tanımıyla aynı pakette bulunduğu sürece gizli olabilir. Yedek olarak, örtülü bağımlılık tanımdan görünür değilse cc_library
hedefine göre kontrol edilir.
Bir kuralın kullanımını belirli paketlerle kısıtlamak isterseniz bunun yerine yük görünürlüğü'nü kullanın.
Görünürlüğü yükle
Yükleme görünürlüğü, bir .bzl
dosyasının geçerli paketin dışındaki diğer BUILD
veya .bzl
dosyalarından yüklenip yüklenemeyeceğini kontrol eder.
Hedef görünürlüğü, hedefler tarafından sarmalanan kaynak kodunu koruduğu gibi, yük 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ük görünürlüğünün korunması olmadığında, makronun aynı çalışma alanındaki diğer ortak çalışanlar tarafından yeniden kullanıldığını ve bu nedenle makronun değiştirilmesi, diğer ekiplerin derlemelerini bozabilir.
Bir .bzl
dosyasının karşılık gelen bir kaynak dosya hedefine sahip olabileceğini veya olmayabileceğini unutmayın.
Çalışıyorsa yük görünürlüğünün ve hedef görünürlüğünün çakışacağı garanti edilmez. Yani aynı BUILD
dosyası, .bzl
dosyasını yükleyebilir ancak bir filegroup
öğesinin srcs
içinde (veya tam tersi) listelenemez. Bu durum, belge oluşturma veya test etme gibi işlemlerde kaynak kodu olarak .bzl
dosyalarını tüketmek isteyen kurallar için bazen sorunlara yol açabilir.
Prototip oluşturma için --check_bzl_visibility=false
değerini ayarlayarak yük görünürlüğü zorunluluğunu devre dışı bırakabilirsiniz. --check_visibility=false
işleminde olduğu gibi, gönderilen kod için bu işlem yapılmamalıdır.
Yük görünürlüğü Bazel 6.0 sürümünden itibaren mevcuttur.
Yük görünürlüğünü bildirme
Bir .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()
bağımsız değişkeni, tıpkı package_group
özelliğinin packages
özelliğinde olduğu gibi paket özelliklerinin bir listesidir. Ancak visibility()
negatif paket özelliklerini 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()
ifadelerinin hemen sonrasında gerçekleşmelidir.
Hedef görünürlüğün aksine, varsayılan yükleme görünürlüğü her zaman herkese açıktır. visibility()
çağırmayan dosyalar her zaman çalışma alanının herhangi bir yerinden yüklenebilir. visibility("private")
öğesini, özellikle paket dışında kullanılmak üzere tasarlanmamış yeni .bzl
dosyalarının en üstüne 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 paket özelliklerini ortak bir liste halinde değerlendirmek 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)
...
Böylece, çeşitli .bzl
dosyalarının görünürlükleri arasında yanlışlıkla sapmalar olmasını önler. Ayrıca clients
listesi geniş olduğunda daha okunaklı olur.
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 listesine 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ılara ve kendi ekibinize ait paketlere görünür olmasını istersiniz. Şunları 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, package_group
açısından yük görünürlüğü 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 özellikleri listesini her iki bildirim türünün de atıfta bulunabileceği bir .bzl dosyasına taşımak en iyisidir. Yukarıdaki Görünürlükleri dikkate alma bölümünde verilen örneğe dayalı olarak aşağıdakileri yazabilirsiniz:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
Bu yalnızca liste herhangi bir negatif paket spesifikasyonu içermediğinde çalışır.
Bağımsız simgeleri koruma
Adı alt çizgi ile başlayan hiçbir Starlark sembolü başka bir dosyadan yüklenemez. Bu yöntem, gizli semboller oluşturmayı kolaylaştırır ancak bu sembolleri sınırlı sayıda güvenilir dosyayla paylaşmanıza izin vermez. Öte yandan, yük görünürlüğü sayesinde .bzl file
, diğer paketlerin neleri görebileceğini kontrol edebilir ancak alt çizgisiz sembollerin yüklenmesini önlemenize izin vermez.
Neyse ki daha hassas bir denetime sahip olmak 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
Kullanıcı internal
veya private
adlı bir dizinden dosya yüklerse, kullanıcının dosyası o dizinin üst öğesinin altında değilse uyarı veren bir Buildifier lint. Bu lint, yük görünürlüğü özelliğinden eskidir ve .bzl
dosyalarının görünürlük bildirdiği çalışma alanlarında gerekli değildir.