本頁面說明 Bazel 的兩種瀏覽權限系統: 目標瀏覽權限和負載瀏覽權限。
這兩種瀏覽權限都能幫助其他開發人員區分 程式庫的公用 API 及其實作詳細資料,有助於強制執行結構 。淘汰公開的資料庫時 API,允許現有使用者同時拒絕新使用者。
目標瀏覽權限
目標瀏覽權限:控管哪些使用者可能取決於你的目標,也就是誰
在 deps
等屬性中使用目標標籤。
如果目標 A
在相同套件中,或只有位於相同套件中,B
目標就可以看到
A
可授予 B
套件的瀏覽權限。因此,套件是
精細程度,進一步決定是否允許存取如果 B
依附 A
但 B
不會顯示 A
,那麼,任何建構 B
嘗試於以下期間都會失敗
「分析」。
請注意,授予套件瀏覽權限,並不會自行授予瀏覽權限 加入子套件如要進一步瞭解套件和子套件,請參閱 概念與術語。
設計原型時,您可以將
標記 --check_visibility=false
。在實際工作環境中的
。
控制瀏覽權限的主要方式是
已啟用「visibility
」屬性
規則目標。本節將說明這個屬性的格式,以及如何
判斷目標的瀏覽權限
瀏覽權限規格
所有規則目標皆具有使用標籤清單的 visibility
屬性。每項
標籤的格式如下。除最後一個表單外
只是語法預留位置,不會對應至任何實際目標。
"//visibility:public"
:授予所有套件的存取權。(無法合併) 其他規格)。"//visibility:private"
:不授予任何額外存取權;僅限目標 這個套件可以使用這個目標(不得與任何其他 specification.)"//foo/bar:__pkg__"
:授予//foo/bar
的存取權 (但沒有授予其存取權 子套件)。"//foo/bar:__subpackages__"
:授予「//foo/bar
」及其所有權限 直接和間接子套件"//some_pkg:my_package_group"
:授予 屬於指定的package_group
。- 套件群組會使用
各種語法
指定套件在套件群組中
"//foo/bar:__pkg__"
和"//foo/bar:__subpackages__"
分別為 由"//foo/bar"
和"//foo/bar/..."
取代。同樣地"//visibility:public"
和"//visibility:private"
只是"public"
和"private"
。
- 套件群組會使用
各種語法
指定套件在套件群組中
例如,如果 //some/package:mytarget
的 visibility
設為
[":__subpackages__", "//tests:__pkg__"]
,則任何目標都能使用此屬性
屬於 //some/package/...
來源樹狀結構的一部分,以及已定義的目標
在 //tests/BUILD
中,但不受 //tests/integration/BUILD
中定義的目標影響。
最佳做法:讓多個目標顯示同一個組合
,請使用 package_group
,而不要在每個套件中重複列出清單
目標的 visibility
屬性。這樣可以提高可讀性,防止
列出無法同步的多個清單
規則目標瀏覽權限
規則目標的瀏覽權限如下:
其
visibility
屬性的值 (如有設定)。或其他如果
default_visibility
敬上package
陳述式的引數 目標的BUILD
檔案 (如果這類宣告存在);或其他//visibility:private
。
最佳做法:避免將 default_visibility
設為公開。大約
原型或小型程式碼集非常方便,但無意間的風險
建立公開目標時,程式碼集會隨著程式碼集的增加而增加。我們建議
哪些目標屬於套件公開介面的一部分。
範例
檔案 //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"],
)
檔案 //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",
],
)
產生的檔案目標瀏覽權限
系統產生的檔案目標瀏覽權限與規則目標相同 產生憑證
來源檔案目標瀏覽權限
您可以藉由呼叫
exports_files
。沒有visibility
時
引數傳遞至 exports_files
,即可公開瀏覽權限。
exports_files
不得用於覆寫所產生檔案的瀏覽權限。
如果來源檔案目標未顯示在呼叫 exports_files
中,
瀏覽權限取決於標記的值
--incompatible_no_implicit_file_export
:
如果設定旗標,瀏覽權限就會是私人狀態。
否則,系統會套用舊版行為:顯示與否與
BUILD
檔案的default_visibility
;如果預設瀏覽權限設為 未指定,
避免依賴舊版行為。一律寫入 exports_files
宣告。
最佳做法:盡可能提供規則目標,而非
來源檔案。舉例來說,與其在 .java
檔案上呼叫 exports_files
,
將檔案包裝在非私人 java_library
目標中。一般而言,規則目標
只能直接參照位於同一套件中的來源檔案。
範例
檔案 //frobber/data/BUILD
:
exports_files(["readme.txt"])
檔案 //frobber/bin/BUILD
:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
配置設定瀏覽權限
先前 Bazel 並未針對以下項目強制執行瀏覽權限:
config_setting
個目標,為
select()
的鍵所參照。有
有兩個標記,可用來移除這個舊版行為:
--incompatible_enforce_config_setting_visibility
敬上 啟用瀏覽權限檢查這些目標為協助進行遷移 也會導致任何未指定visibility
的config_setting
會視為公開 (無論套件層級default_visibility
為何)。--incompatible_config_setting_private_default_visibility
敬上 如果config_setting
未指定visibility
,就會遵循 套件的default_visibility
和備用私人瀏覽權限設為備用 和任何其他規則目標一樣如果 未設定「--incompatible_enforce_config_setting_visibility
」。
避免依賴舊版行為。用於意圖的任何 config_setting
用於目前套件以外的環境,應具有明確的 visibility
(如果
套件尚未指定合適的 default_visibility
。
套件群組目標瀏覽權限
package_group
目標不含 visibility
屬性。這些都是
公開顯示。
隱含依附元件的瀏覽權限
部分規則具有隱含依附元件:
未寫到 BUILD
檔案中,但對應的依附元件
套用該規則的每個例項舉例來說,cc_library
規則可能會建立
隱含依附性從其個別規則目標到可執行的目標
代表 C++ 編譯器
系統會根據
套件,內含定義規則 (或切面) 的 .bzl
檔案。於
如範例所示,只要 C++ 編譯器位於
做為 cc_library
規則的定義。如果
定義中不會顯示隱含依附元件,系統會使用以下條件進行檢查
參照 cc_library
目標。
如要變更這項行為,請停用
--incompatible_visibility_private_attributes_at_definition
。
停用後,系統會將隱含依附元件視為任何其他依附元件。
這表示,相依的目標 (例如 C++ 編譯器) 必須
所有執行個體都能看到這個狀態在實務上,這通常代表
必須公開顯示
如要限制特定套件的使用規則,請使用 載入瀏覽權限。
載入瀏覽權限
載入瀏覽權限控管 .bzl
檔案能否從其他來源載入
BUILD
或 .bzl
檔案。
以相同方式保護封裝的原始碼
負載瀏覽權限可保護由 .bzl
封裝的建構邏輯
檔案。舉例來說,BUILD
檔案作者可能想考慮部分重複情形
將定義轉換為巨集,以在 .bzl
檔案中。沒有負載防護
瀏覽權限時,他們可能會發現其他協作者在
以防修改巨集造成其他團隊建構應用程式
請注意,.bzl
檔案不一定有對應的來源檔案目標。
如果確實如此,則無法保證載入可視性和目標
顯示設定也就是說,同一個 BUILD
檔案或許也能載入
.bzl
檔案,但並未列在 filegroup
的 srcs
中,
反之亦然這有時可能會導致想使用的規則發生問題
.bzl
檔案做為原始碼,例如用於產生文件或測試文件。
進行原型設計時,您可以透過
--check_bzl_visibility=false
。和 --check_visibility=false
一樣,這個項目應該
未完成的標記作業
自 Bazel 6.0 起才能使用載入瀏覽權限。
宣告負載瀏覽權限
如要設定 .bzl
檔案的載入瀏覽權限,請呼叫
檔案中的 visibility()
函式。
visibility()
的引數是套件規格清單,就像這樣
應用程式的 packages
屬性
package_group
。不過,visibility()
不接受排除套件
規格。
在頂層,對 visibility()
的呼叫只能為每個檔案執行一次 (非在頂層)
最好緊接在函式之後),最好緊接在 load()
陳述式之後。
不同於目標瀏覽權限,預設的載入顯示一律為公開。檔案
凡是未呼叫 visibility()
的項目,一律可從
工作區建議您將 visibility("private")
新增至
新的 .bzl
檔案,並非專門在套件外使用。
範例
# //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
...
載入瀏覽權限做法
本節說明管理載入瀏覽權限宣告的訣竅。
因式分解顯示設定
如有多個 .bzl
檔案的瀏覽權限相同,可協助你
會將套件規格納入常見清單例如:
# //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)
...
這有助於避免多個 .bzl
檔案之間意外偏移
檢視權限當 clients
清單較大時,更方便閱讀。
撰寫顯示設定
有時候,您可能需要允許存取 .bzl
檔案的許可清單
由多個較小的許可清單組成。這類似於
package_group
可以透過package_group
includes
屬性。
假設您要淘汰廣泛使用的巨集。您希望讓所有人都能看見這項資訊 轉移到您團隊擁有的套件中。您可以撰寫:
# //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)
複製套件群組
有別於目標可見性,您無法在
package_group
。如要針對兩個目標重複使用相同的許可清單
建議您移動套件清單
規格轉換為 .bzl 檔案,這兩種宣告可能指稱
基礎架構以因素顯示瀏覽權限範例為基礎
就可以寫成:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
只有在清單不含任何排除套件時,才能使用這個方法 規格。
保護個別符號
無法載入任何名稱開頭為底線的 Starlark 符號
另一個檔案這可讓您輕鬆建立私人符號,但不允許使用
可讓您與少量可信任的檔案分享這些符號。另一部
載入顯示設定,控制其他套件可以查看
.bzl file
,但無法讓您阻止任何非底線的符號
載入狀態。
幸好,您可以結合這兩項功能,獲得精細的控制選項。
# //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 建構工具 Lint
有建構工具 Lint
當使用者從名為 internal
的目錄載入檔案時,系統會提供警告訊息
或 private
(使用者檔案本身並非位於該父項的父項之下)
目錄。此 Lint 會早於載入能見度功能,因此不需要
為 .bzl
檔案宣告瀏覽權限的工作區。