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ıyı zorunlu kılmaya yardımcı olur. Mevcut kullanıcılara izin verirken yeni kullanıcıları reddetmek için herkese açık bir API'yi kullanımdan kaldırırken de görünürlüğü kullanabilirsiniz.
Hedef görünürlüğü
Hedef görünürlüğü, hedefinize bağlı olabilecek kişileri (yani hedefinizin etiketini deps
gibi bir özellik içinde kimlerin kullanabileceğini) kontrol eder.
Bir hedef A
, bir B
hedefi aynı paket içindeyse veya A
, B
paketine görünürlük sağlıyorsa bu hedef tarafından görülebilir. Bu nedenle paketler, erişime izin verilip verilmeyeceğine karar verirken kullanılan ayrıntı birimidir. B
, A
bağımlıysa ancak A
, B
tarafından görünmüyorsa analiz sırasında B
derleme denemeleri başarısız olur.
Bir pakete görünürlük sağlamanın, 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üğü uygulaması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 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 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öz dizimi yer tutucularıdır.
"//visibility:public"
: Tüm paketlere erişim izni verir. (Başka herhangi bir spesifikasyonla birleştirilemez.)"//visibility:private"
: Herhangi bir ek erişim izni vermez. Yalnızca bu paketteki hedefler bu hedefi kullanabilir. (Diğer spesifikasyonlarla birleştirilemez.)"//foo/bar:__pkg__"
://foo/bar
için erişim izni verir (ancak alt paketlerine erişim izni vermez)."//foo/bar:__subpackages__"
://foo/bar
uygulamasına 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 bir şekilde,"//visibility:public"
ve"//visibility:private"
yalnızca"public"
ve"private"
'dir.
- 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 öğe, //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: Birkaç hedefi aynı paket grubuna görünür hale getirmek için her bir hedefin visibility
özelliğinde listeyi tekrarlamak yerine bir package_group
kullanın. Bu, okunabilirliği artırır ve listelerin senkronize
olmasını önler.
Kural hedefi görünürlüğü
Bir kural hedefinin görünürlüğü şudur:
Ayarlanmışsa
visibility
özelliğinin değeri veya aksi takdirdeBöyle bir beyan 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 yöntem, prototip oluşturmak veya küçük kod tabanlarında kullanım için elverişli olabilir. Ancak kod tabanı büyüdükçe, yanlışlıkla herkese açık hedefler oluşturma riski de artar. Hangi hedeflerin, paketin herkese açık arayüzünün parçası olduğunu açıkça belirtmek daha iyidir.
Örnek
//frobber/bin/BUILD
dosyası:
# 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"],
)
//frobber/BUILD
dosyası:
# 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 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 bir şekilde ayarlayabilirsiniz. exports_files
için 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 --incompatible_no_implicit_file_export
değerine bağlıdır:
İşaret ayarlanırsa görünürlük gizli olur.
Diğer durumlarda eski davranış geçerlidir: Görünürlük
BUILD
dosyasınındefault_visibility
özelliğiyle aynıdır veya varsayılan görünürlük belirtilmezse gizli olur.
Eski davranışa güvenmekten kaçının. 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 kural hedefi göstermeyi tercih edin. Örneğin, .java
dosyasında exports_files
öğesini çağırmak yerine dosyayı gizli olmayan bir java_library
hedefi içinde sarmalayın. Genel olarak, kural hedefleri yalnızca aynı pakette bulunan kaynak dosyalarına doğrudan başvuruda bulunmalıdır.
Ö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üğü
Geçmişte Bazel, select()
anahtarlarında başvurulan config_setting
hedefleri için görünürlük zorunlu tutmadı. Bu eski davranışı kaldırmanın iki işareti 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 amacıyla, birvisibility
belirtmeyenconfig_setting
öğelerinin herkese açık olarak kabul edilmesine de neden olur (paket düzeyindedefault_visibility
ne olursa olsun).--incompatible_config_setting_private_default_visibility
,visibility
belirtmeyenconfig_setting
öğelerinin, paketindefault_visibility
politikasına uymasına ve diğer kural hedeflerinde olduğu gibi gizli görünürlük ayarına dönmesine neden olur.--incompatible_enforce_config_setting_visibility
ayarlanmazsa işlem yapılamaz.
Eski davranışa güvenmekten kaçının. Mevcut paketin dışında kullanılması amaçlanan herhangi bir config_setting
, pakette zaten uygun bir default_visibility
belirtilmiyorsa açık bir visibility
içermelidir.
Paket grubu hedefi görünürlüğü
package_group
hedeflerinde visibility
özelliği yok. Bu dosyalar her zaman
her zaman görünür durumdadır.
Örtülü bağımlılıkların görünürlüğü
Bazı kuralların dolaylı bağımlılıkları vardır. Bunlar bir BUILD
dosyasında yazılmamış olan ancak söz konusu kuralın her örneğinde yerleşik olan bağımlılıklardır. Örneğin bir cc_library
kuralı, kural hedeflerinin her birinden bir C++ derleyicisini temsil eden yürütülebilir bir hedefe yönelik örtülü bir bağımlılık oluşturabilir.
Şu anda, görünürlük amacıyla bu dolaylı bağımlılıklar diğer herhangi bir bağımlılık gibi ele alınmaktadır. Bu, bağımlı olan hedefin (ör. C++ derleyicimiz) kuralın her örneğinde görünür olması gerektiği anlamına gelir. Pratikte bu, genellikle hedefin herkes tarafından görülebilir olması gerektiği anlamına gelir.
--incompatible_visibility_private_attributes_at_definition
ayarını yaparak bu davranışı değiştirebilirsiniz. Etkinleştirildiğinde, söz konusu hedefin yalnızca örtülü bağımlılık olduğunu belirten kural tarafından görülebilmesi gerekir. Yani, kuralın tanımlandığı .bzl
dosyasını içeren paket tarafından görülebilmelidir. Örneğimizde C++ derleyicisi, cc_library
kuralının tanımıyla aynı pakette olduğu sürece gizli 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üklenmeyeceğini kontrol eder.
Hedef görünürlüğün, hedefler tarafından kapsüllenmiş kaynak kodunu koruduğu gibi, yük görünürlüğü de .bzl
dosyaları tarafından içine alınan derleme mantığını korur. Örneğin bir BUILD
dosyasının yazarı, .bzl
dosyasındaki bazı tekrarlanan hedef tanımlarını bir makroya dahil etmek isteyebilir. Yük görünürlüğünün korunması olmadan, makrolarının aynı çalışma alanındaki diğer ortak çalışanlar tarafından yeniden kullanıldığını bulabilirler. Bu nedenle, makronun değiştirilmesi diğer ekiplerin derlemelerini bozar.
Bir .bzl
dosyasının karşılık gelen bir kaynak dosya hedefine sahip olabileceğini veya olmayabileceğini unutmayın.
Eşleşirse yük görünürlüğünün ve hedef görünürlüğün çakışacağı garanti edilmez. Diğer bir deyişle, aynı BUILD
dosyası .bzl
dosyasını yükleyebilir ancak bir filegroup
öğesinin srcs
içinde (veya tam tersi) listeleyemez. Bu durum, doküman oluşturma veya test etme gibi kaynak kodu olarak .bzl
dosyalarını kullanmak 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üğünün zorunlu kılınmasını devre dışı bırakabilirsiniz. --check_visibility=false
işleminde olduğu gibi, gönderilen kod için
bu yapılmamalıdır.
Yük görünürlüğü Bazel 6.0'dan 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, package_group
öğesinin packages
özelliği gibi, paket özelliklerinin 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 ardından 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ındaki herhangi bir yerden yüklenebilir. Özel olarak paket dışında kullanılmak üzere tasarlanmamış 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 çarpanlarına ayırma
Birden fazla .bzl
dosyasının aynı görünürlüğe sahip olması gerektiğinde paket özelliklerini ortak bir liste halinde eklemek 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 sapmaları önlemeye yardımcı olur. Ayrıca, clients
listesi geniş olduğunda daha okunabilir olur.
Görünürlük oluşturma
Bazen bir .bzl
dosyasının, birden fazla küçük izin verilenler listesinden oluşan bir izin verilenler listesinde görünür olması gerekebilir. Bu, bir package_group
öğesinin includes
özelliği aracılığıyla diğer package_group
öğelerini nasıl dahil edebileceğine 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ı istiyorsunuz. Ş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 çoğaltma
Hedef görünürlüğün aksine, yük görünürlüğünü package_group
terimleriyle 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 referans gösterebileceği bir .bzl dosyasına taşımanız önerilir. Yukarıdaki Görünürlükleri göz önünde bulundurma bölümündeki örneği derleyerek 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çermiyorsa işe yarar.
Bağımsız sembolleri koruma
Adı alt çizgiyle başlayan Starlark sembolleri başka bir dosyadan yüklenemez. Bu işlem, gizli sembolleri oluşturmayı kolaylaştırır ancak bu simgeleri sınırlı sayıda güvenilir dosyayla paylaşmanıza izin vermez. Öte yandan, yük görünürlüğü, diğer paketlerin .bzl file
öğesini görebileceklerini kontrol etmenizi sağlar ancak alt çizgisiz simgelerin yüklenmesini engellemenize 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-görünürlük Bücre lint
Kullanıcılar internal
veya private
adlı bir dizinden dosya yüklerse ve kullanıcı dosyasının kendisi o dizinin üst öğesinin altında değilse uyarı veren bir Buildifier lint bulunur. Bu lint, yükleme 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.