Görünürlük

Sorun bildir Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bu sayfada Bazel'in 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 sizin kitaplığının herkese açık API'sini ve uygulama ayrıntılarını öğrenme, ayrıca yapının sahip olmanız gerekir. Görünürlüğü, herkese açık bir içeriği kullanımdan kaldırırken de kullanabilirsiniz Mevcut kullanıcılara izin verirken yenilerini reddederken API.

Hedef görünürlük

Hedef görünürlük, hedefinize kimlerin bağlı olabileceğini, yani hedefinizin etiketini deps gibi bir özelliğin içinde kullanın.

Bir hedef A, aynı paketteyse veya hedef B tarafından görülebilir A, B paketine görünürlük izni verir. Bu nedenle paketler, ayrıntı düzeyini kontrol eder. B, A metriğine bağlıysa ancak A, B tarafından görülemez. Bu durumda B derlemesi girişimleri, analiz yapın.

Bir pakete görünürlük vermenin tek başına görünürlük sağlamayacağını unutmayın ekler. Paket ve alt paketler hakkında daha fazla ayrıntı için bkz. Kavramlar ve terminoloji.

Prototip oluşturmak için --check_visibility=false olarak işaretle. Bu işlem, gönderilmiştir.

Görünürlüğü denetlemenin birincil yolu visibility özelliği açık kural hedeflerini belirlemenize yardımcı olur. Bu bölümde, bu özelliğin biçimi ve bir hedefin görünürlüğünü saptar.

Görünürlük spesifikasyonları

Tüm kural hedeflerinde, etiketler listesini alan bir visibility özelliği bulunur. Her biri etiketi aşağıdaki biçimlerden birine sahiptir. Son form hariç, bunlar yalnızca gerçek bir hedefe karşılık gelmeyen söz dizimsel yer tutuculardır.

  • "//visibility:public": Tüm paketlere erişim izni verir. (Birleştirilemez dikkat edin.)

  • "//visibility:private": Ek erişim izni vermez; yalnızca hedef bu hedefi kullanabilir. ( specification.)

  • "//foo/bar:__pkg__": //foo/bar için erişim izni verir (ancak alt paketler).

  • "//foo/bar:__subpackages__": //foo/bar ve tüm özelliklerine erişim izni verir alt paketlere dahil edilir.

  • "//some_pkg:my_package_group": Pakete dahil olan tüm paketlere erişim izni verir belirtilen package_group öğelerinin bir parçasıdır.

    • Paket grupları, farklı söz dizimi belirtir. Bir paket grubunda Sırasıyla "//foo/bar:__pkg__" ve "//foo/bar:__subpackages__" "//foo/bar" ve "//foo/bar/..." ile değiştirildi. Aynı şekilde, "//visibility:public" ve "//visibility:private" yalnızca "public" ve "private".

Örneğin, //some/package:mytarget için visibility değeri [":__subpackages__", "//tests:__pkg__"], herhangi bir hedef tarafından kullanılabilir yanı sıra tanımlanan hedeflerin bir parçası olan //some/package/... içinde //tests/BUILD var, ancak //tests/integration/BUILD içinde tanımlanan hedeflerle değil.

En iyi uygulama: Aynı küme için birkaç hedefi görünür hale getirmek her birinde listeyi tekrarlamak yerine bir package_group kullanın hedefin visibility özelliğine Bu, okunabilirliği artırır ve senkronize olmasını engeller.

En iyi uygulama: Başka bir ekibin projesine görünürlük verirken gereksiz görünürlük kaybı olmaması için __pkg__ üzerinden __subpackages__ ve yeni alt paketler eklenir.

Kural hedef görünürlüğü

Bir kural hedefinin görünürlüğü:

  1. Ayarlanırsa visibility özelliğinin değeri; veya başka

  2. The value of default_visibility package ifadesinin bağımsız değişkenindeki hedefin BUILD dosyasını (bu tür bir beyan varsa); veya başka

  3. //visibility:private.

En iyi uygulama: default_visibility öğesini herkese açık olarak ayarlamaktan kaçının. olabilir küçük kod tabanları için uygun olsa da başarısız olma riski vardır. herkese açık hedefler oluşturmak, kod tabanı büyüdükçe artar. Proje yöneticisi olmaktan hangi hedeflerin paketin herkese açık arayüzünde yer aldığını açıkça belirtir.

Ö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 bir dosya hedefi, üretir.

Kaynak dosya hedefi görünürlüğü

Bir kaynak dosya hedefinin görünürlüğünü açıkça ayarlamak için exports_files. visibility olmadığında bağımsız değişkeni exports_files parametresine geçirildiğinde görünürlüğü herkese açık hale getirir. 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, bayrağın değerine bağlıdır --incompatible_no_implicit_file_export:

  • Bayrak ayarlanırsa görünürlük gizli olur.

  • Aksi takdirde, eski davranış geçerlidir: Görünürlük BUILD dosyasının default_visibility ayarı veya varsayılan görünürlük ayarı şuysa gizli: belirtilmedi.

Eski davranışı kullanmaktan kaçının. Her zaman exports_files yaz bildirimi almaz.

En iyi uygulama: Mümkün olduğunda, kaynak dosya. Örneğin, .java dosyasında exports_files işlevini çağırmak yerine, dosyayı gizli olmayan bir java_library hedefi içine sarmalar. Genellikle kural hedefleri yalnızca aynı paket içinde bulunan kaynak dosyalara 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, müşterilerini hedefleyen config_setting hedef bir select() anahtarlarında başvuruda bulunuldu. Orada bu eski davranışı kaldırmaya yönelik iki işaret vardır:

  • --incompatible_enforce_config_setting_visibility bu hedeflerin görünürlüğünün kontrolünü etkinleştirir. Taşımaya yardımcı olması için bir visibility belirtmeyen herhangi bir config_setting öğesinin herkese açık olarak kabul edilir (paket düzeyinde default_visibility bağımsız olarak).

  • --incompatible_config_setting_private_default_visibility bir visibility belirtmeyen config_setting'lerin paketinin default_visibility gizli olduğundan emin olmak için diğer tüm kural hedefleri gibidir. Aşağıdaki durumlarda herhangi bir --incompatible_enforce_config_setting_visibility ayarlanmadı.

Eski davranışı kullanmaktan kaçının. Şunları hedefleyen herhangi bir config_setting: kullanımının geçerli paketin dışında kullanılması için açık bir visibility olmalıdır. paketinde uygun bir default_visibility bulunmuyor.

Paket grubu hedef görünürlüğü

package_group hedeflerin visibility özelliği yok. Her zaman herkes tarafından görülebilir.

Dolaylı bağımlılıkların görünürlüğü

Bazı kuralların dolaylı bağımlılıkları vardır. BUILD dosyasında belirtilmemiş ancak doğasında olan bağımlılıklar tekrarlamanız gerekir. Örneğin, bir cc_library kuralı kural hedeflerinin her birinden yürütülebilir bir hedefe örtülü bağımlılık temsil eder.

Böyle bir örtülü bağımlılığın görünürlüğü, kuralın (veya unsurun) tanımlandığı .bzl dosyasını içeren paket. İçinde Örneğimize göre C++ derleyicisi, aynı paketinin tamamını cc_library kuralının tanımı olarak tanımlar. Yedek olarak örtülü bağımlılık tanımdan görünmez. Bu bağımlılık cc_library hedefine göre.

Bir kuralın kullanımını belirli paketlerle kısıtlamak istiyorsanız yük görünürlüğü oluşturun.

Görünürlüğü yükle

Yükleme görünürlüğü, bir .bzl dosyasının diğer BUILD veya .bzl dosyası, geçerli paketin dışında.

Tıpkı hedef görünürlüğün, kapsüllenmiş kaynak kodunu koruduğu gibi yük görünürlüğü, .bzl tarafından kapsüllenen derleme mantığını korur. dosyası olarak da kaydedebilir. Örneğin, BUILD dosyasının yazarı bazı yinelemeleri hesaba katmak isteyebilir hedef tanımlarını .bzl dosyasında bir makroya dönüştürmenizi sağlar. Yük koruması olmadan makronun diğer ortak çalışanlar tarafından yeniden kullanıldığını aynı çalışma alanında yer alması ve makronun değiştirilmesinin diğer ekiplerin inşa eder.

Bir .bzl dosyasının karşılık gelen bir kaynak dosya hedefinin olabileceğini veya olmayabileceğini unutmayın. Görünüyorsa yük görünürlüğünün ve hedefin örtüşüyor. Yani aynı BUILD dosyası, .bzl dosyası vardır ancak filegroup öğesinin srcs içinde listelenmez veya tam tersi. Bu durum bazen, kod snippet'ini kullanmak isteyen kurallar için .bzl dosyalarını kaynak kodu olarak yükleyebilirsiniz (örneğin, doküman oluşturma veya test için).

Prototip oluşturmak için şu ayarı yaparak yük görünürlüğünün uygulanmasını devre dışı bırakabilirsiniz: --check_bzl_visibility=false --check_visibility=false konusunda olduğu gibi, yapılmaması gerekir.

Yükleme görünürlüğü, Bazel 6.0'dan itibaren kullanılabilmektedir.

Yük görünürlüğü beyan ediliyor

Bir .bzl dosyasının yükleme görünürlüğünü ayarlamak için şunu çağırın: visibility() işlevini dosyadan kullanırsınız. visibility() bağımsız değişkeni, şunun packages özelliği: package_group. Ancak visibility() negatif paketi kabul etmiyor özellikler.

visibility() çağrısı, üst düzeyde, dosya başına yalnızca bir kez yapılmalıdır ( içinde) ve ideal olarak load() ifadelerinin hemen ardından kullanılmasıdır.

Hedef görünürlüğün aksine, varsayılan yükleme görünürlüğü her zaman herkese açıktır. Dosyalar visibility() işlevini çağırmayanlar her zaman çalışmayacaktır. Herhangi bir listenin en üstüne visibility("private") özel olarak paket dışında kullanılmak üzere tasarlanmamış yeni .bzl dosyası.

Ö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ı gerekiyorsa aşağıdakileri yapmak yararlı olabilir: ortak bir listeye dahil etmeleri gerekir. Ö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ı arasında kazayla oluşan sapmaları önlemeye yardımcı olur her şeyi kapsıyor. Ayrıca clients listesi büyük olduğunda daha okunaklı olur.

Görünürlükleri oluşturma

Bazen bir .bzl dosyasının izin verilenler listesi içerir. Bu, bir kurumun package_group ile diğer package_group includes özelliğiyle birlikte kullanılamaz.

Yaygın olarak kullanılan bir makroyu kullanımdan kaldırdığınızı varsayalım. Yalnızca görünür olmasını istiyorsanız ve kendi ekibinizin sahip olduğu paketler için otomatik olarak eklenir. Şöyle 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 Her iki hedef için de aynı izin verilenler listesini yeniden kullanmak istiyorsanız görünürlük ve yük görünürlüğünün az olduğu durumlarda, en iyi seçenek özelliklerini bir .bzl dosyası olarak kaydeder. Burada, her iki bildirim türü de somut olarak ortaya koyar. Görünürlükleri dikkate alma başlıklı makaleden devam ederek buraya şöyle yazabilirsiniz:

# //mylib/BUILD

load(":internal_defs", "clients")

package_group(
    name = "my_pkg_grp",
    packages = clients,
)

Bu işlem yalnızca listede herhangi bir negatif paket yoksa çalışır özellikler.

Tek tek sembolleri koruma

Adı alt çizgiyle başlayan hiçbir Starlark sembolü şuradan yüklenemez: ekleyebilirsiniz. Bu, gizli sembol oluşturmayı kolaylaştırır ancak bu simgeleri sınırlı sayıda güvenilir dosyayla paylaşmanızı sağlar. Diğer Ancak yük görünürlüğü, diğer paketlerin size veya .bzl file alt çizgisi olmayan simgelerin yükleniyor.

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-görünürlük Derlemesi Aracı lint'i

Buildifier lint (Oluşturucu lint) vardır Kullanıcılar internal adlı dizinden dosya yüklerse uyarı verir veya private (kullanıcının dosyası, söz konusu dosyanın üst öğesi altında olmadığında) dizin. Bu hata analizi, yükleme görünürlüğü özelliğinden önce çalışır ve .bzl dosyasının görünürlük bildirdiği çalışma alanları.