常見定義

回報問題 查看原始碼 Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

本節定義許多函式或建構規則的常見術語和概念。

目錄

Bourne 殼層符記化

部分規則的特定字串屬性會根據 Bourne 殼層的符號化規則分割成多個字詞:未加上引號的空格會用來分隔不同的字詞,而單引號、雙引號字元和反斜線則可用來防止符號化。

本文件中定義的屬性,如果需要經過此符記化程序,就會明確標示為此類屬性。

屬性會受到「Make」變數展開和 Bourne shell 符記化處理,通常用於將任意選項傳遞至編譯器和其他工具。這類屬性的例子包括 cc_library.coptsjava_library.javacopts。這些替換項目可讓單一字串變數擴充為特定設定的選項字詞清單。

標籤展開

少數規則的部分字串屬性會受到標籤展開功能的影響:如果這些字串包含有效標籤做為子字串 (例如 //mypkg:target),且該標籤是目前規則宣告的必要條件,則會展開為 target //mypkg:target 所代表的檔案路徑。

屬性範例包括 genrule.cmdcc_binary.linkopts。在各個情況下,詳細資料可能會大不相同,例如:是否要展開相對標籤;如何處理展開至多個檔案的標籤等等。請參閱規則屬性說明文件,瞭解詳細資訊。

大多數建構規則定義的一般屬性

本節將說明許多建構規則定義的屬性,但並非全部。

屬性 說明
data

標籤清單;預設為 []

這項規則在執行階段所需的檔案。可能會列出檔案或規則目標。一般來說,允許任何目標。

data 屬性中目標的預設輸出內容和執行檔,應顯示在任何可執行檔的 *.runfiles 區域中,這些可執行檔是由此目標輸出,或對此目標具有執行階段依附元件。這可能包括執行此目標的 srcs 時所使用的資料檔案或二進位檔。如要進一步瞭解如何依附及使用資料檔案,請參閱「資料相依性」一節。

如果新規則會處理在執行階段可能會使用其他輸入內容的輸入內容,則應定義 data 屬性。規則的實作函式也必須從任何 data 屬性的輸出內容和執行檔,以及提供原始碼或執行階段依附元件的任何依附元件屬性,填入目標的執行檔

deps

標籤清單;預設為 []

這個目標的依附元件。一般來說,您只應列出規則的目標。(雖然某些規則允許直接在 deps 中列出檔案,但應盡量避免這麼做)。

語言專屬規則通常會將列出的目標限制為特定供應商

使用 deps 時,目標依賴另一個目標的確切意義會因規則類型而異,規則專屬文件會提供更多詳細資訊。對於處理原始碼的規則,deps 通常會指定 srcs 中程式碼使用的程式碼依附元件。

通常,deps 依附元件會用於讓一個模組使用在其他模組中定義的符號,這些符號是使用相同的程式設計語言編寫並個別編譯。在許多情況下,跨語言依附元件也允許使用:例如,java_library 目標可能會依附 cc_library 目標中的 C++ 程式碼,方法是將後者列在 deps 屬性中。詳情請參閱「依附元件」的定義。

licenses

字串清單;不可設定;預設為 ["none"]

這個特定目標要使用的授權類型字串清單。這是已淘汰的授權 API 的一部分,Bazel 不再使用此 API。請勿使用此選項。

srcs

標籤清單;預設為 []

這項規則處理或納入的檔案。通常會直接列出檔案,但也可能會列出規則目標 (例如 filegroupgenrule),以納入其預設輸出內容。

特定語言的規則通常會要求列出的檔案具有特定副檔名。

所有建構規則的共同屬性

本節說明會隱含新增至所有建構規則的屬性。

屬性 說明
compatible_with

標籤清單;無法設定;預設為 []

除了預設支援的環境外,此目標可建構的環境清單。

這是 Bazel 限制系統的一部分,可讓使用者宣告哪些目標可以相互依附,哪些不行。舉例來說,外部可部署的二進位檔不應依附含有公司機密程式碼的程式庫。詳情請參閱 ConstraintSemantics

deprecation

字串;不可設定;預設值為 None

與此目標相關的說明警告訊息。這項資訊通常用於通知使用者,某個目標已淘汰、已由其他規則取代、僅適用於某個套件,或可能因某些原因而被視為有害。建議您加入一些參考資料 (例如網頁、錯誤編號或遷移 CL 範例),方便他人輕鬆找出需要進行哪些變更才能避免出現這則訊息。如果有可用來取代舊目標的新目標,建議您只遷移舊目標的所有使用者。

這個屬性不會影響建構方式,但可能會影響建構工具的診斷輸出。如果套件中的目標依賴具有 deprecation 屬性的規則,建構工具就會發出警告。

套件內部依附元件不受此警告限制,因此,例如建構已淘汰規則的測試時,不會遇到警告。

如果已淘汰的目標依附於另一個已淘汰的目標,系統不會發出警告訊息。

使用者停止使用後,您就可以移除目標。

distribs

字串清單;不可設定;預設為 []

要用於這個特定目標的發布方法字串清單。這是已淘汰的授權 API 的一部分,Bazel 不再使用此 API。請勿使用此選項。

exec_compatible_with

標籤清單;不可設定;預設為 []

此目標的執行平台中必須具備的 constraint_values 清單。這是在規則類型已設定的任何限制之外。限制可用執行平台的清單。詳情請參閱工具鍊解析的說明。

exec_properties

字串字典;預設為 {}

字串字典,會新增至為此目標所選平台的 exec_properties。請參閱 platform 規則的 exec_properties

如果平台和目標層級屬性都包含鍵,系統會從目標取得值。

features

feature 字串清單;預設為 []

功能是可在目標上啟用或停用的字串代碼。特徵的意義取決於規則本身。

這個 features 屬性會與 包裝層級的 features 屬性結合。舉例來說,如果在套件層級啟用功能 ["a"、"b"],且目標的 features 屬性包含 ["-a"、"c"],則為此規則啟用的功能將為 "b" 和 "c"。 查看範例

restricted_to

標籤清單;無法設定;預設為 []

這個目標可以建構的環境清單,而非系統預設支援的環境。

這是 Bazel 限制系統的一部分。詳情請參閱 compatible_with

tags

字串清單;不可設定;預設為 []

標記可用於任何規則。測試和 test_suite 規則的標記可用於分類測試。非測試目標的標記可用於控制 genruleStarlark 動作的沙箱執行作業,並供人類和/或外部工具剖析。

如果 Bazel 在任何測試或 genrule 目標的 tags 屬性,或任何 Starlark 動作的 execution_requirements 鍵中,找到下列關鍵字,就會修改沙箱程式的行為。

  • no-sandbox 關鍵字會導致動作或測試永遠不會進入沙箱;仍可快取或遠端執行 - 請使用 no-cacheno-remote 來防止這兩種情況。
  • no-cache 關鍵字會導致動作或測試永遠不會快取 (遠端或本機)
  • no-remote-cache 關鍵字會導致動作或測試永遠不會在遠端快取 (但可能會在本機快取;也可能會在遠端執行)。注意:就本代碼而言,磁碟快取會視為本機快取,而 HTTP 和 gRPC 快取則視為遠端快取。如果同時使用本機磁碟快取和遠端快取 (結合式快取),系統會將其視為遠端快取並完全停用,除非設定 --incompatible_remote_results_ignore_disk,否則會使用本機元件。
  • no-remote-exec 關鍵字會導致動作或測試永遠不會從遠端執行 (但可能會從遠端快取)。
  • no-remote 關鍵字可防止動作或測試從遠端執行或快取。這相當於同時使用 no-remote-cacheno-remote-exec
  • no-remote-cache-upload 關鍵字會停用產生作業的遠端快取上傳部分。不會停用遠端執行作業。
  • local 關鍵字可防止動作或測試遭到遠端快取、遠端執行或在沙箱中執行。對於 genrules 和測試,使用 local = True 屬性標記規則會產生相同的效果。
  • requires-network 關鍵字可讓沙箱內的應用程式存取外部網路。只有在啟用沙箱功能時,這個標記才會生效。
  • block-network 關鍵字會封鎖從沙箱內存取外部網路的存取權。在這種情況下,系統只允許與本機進行通訊。只有在啟用沙箱功能時,這個標記才會生效。
  • requires-fakeroot 會以 uid 和 gid 0 (即 root 使用者) 執行測試或動作。這項功能僅支援 Linux。這個標記的優先順序高於 --sandbox_fake_username 指令列選項。

測試的標記通常用於在偵錯和發布程序中標註測試的角色。一般來說,標記最適合用於 C++ 和 Python 測試,因為這兩者缺乏任何執行階段註解功能。使用標記和大小元素,可根據程式碼庫簽入政策,靈活組合測試套件。

如果 Bazel 在測試規則的 tags 屬性中找到下列關鍵字,就會修改測試執行行為:

  • exclusive 會強制以「專屬」模式執行測試,確保不會同時執行其他測試。在所有建構活動和非專屬測試完成後,這類測試會以序列方式執行。對於這類測試,系統會停用遠端執行功能,因為 Bazel 無法控制在遠端機器上執行的內容。
  • 如果在本機執行,exclusive-if-local 會強制以「專屬」模式執行測試,但如果在遠端執行,則會並行執行測試。
  • manual 關鍵字會在計算要為 buildtestcoverage 指令建構/執行的頂層目標集合時,將目標排除在目標模式萬用字元 (...:*:all 等) 和 test_suite 規則的展開作業之外,這些規則不會明確列出測試。這不會影響其他情境 (包括 query 指令) 中的目標萬用字元或測試套件擴充功能。請注意,manual 並非表示目標不應由持續建構/測試系統自動建構/執行。舉例來說,您可能會希望從 bazel test ... 中排除目標,因為該目標需要特定的 Bazel 標記,但仍可納入正確設定的提交前或持續測試執行作業。
  • external 關鍵字會強制執行測試 (無論 --cache_test_results 值為何)。
如要進一步瞭解附加至測試目標的標記慣例,請參閱「測試百科全書」中的「標記慣例」。
target_compatible_with

標籤清單;預設為 []

清單中列出目標平台必須具備的 constraint_value,才能將這個目標視為相容。除了規則類型已設定的任何限制外,如果目標平台不符合所有列出的限制條件,則系統會將目標視為「不相容」。當目標模式展開 (例如 //...:all) 時,系統會略過不相容的目標,以便建構及測試。如果在指令列中明確指定不相容的目標,Bazel 會列印錯誤訊息,並導致建構或測試失敗。

依附於不相容目標的目標,本身也視為不相容。建構和測試作業也會略過這些項目。

空白清單 (預設值) 表示目標與所有平台相容。

除了「工作區規則」以外,所有規則都支援這項屬性。對於某些規則,這個屬性不會有任何作用。舉例來說,為 cc_toolchain 指定 target_compatible_with 並無用處。

如要進一步瞭解不相容的目標略過功能,請參閱「平台」頁面。

testonly

布林值;不可設定;預設值為 False,但測試和測試套件目標除外

如果是 True,則只有 testonly 目標 (例如測試) 可以依附此目標。

同樣地,如果規則不是 testonly,則不得依附任何 testonly 規則。

測試 (*_test 規則) 和測試套件 (test_suite 規則) 預設為 testonly

這個屬性意指目標不應包含在發布至實際工作環境的二進位檔中。

由於 testonly 是在建構階段而非執行階段強制執行,且會透過依附元件樹狀結構進行傳播,因此應謹慎套用。舉例來說,用於單元測試的輔助程式和假設也可能用於涉及將發布至實際工作環境的相同二進位檔的整合測試,因此不應標示為「testonly」。相反地,連連結都可能造成危險的規則 (可能是因為無條件覆寫正常行為),應標示為「testonly」。

toolchains

標籤清單;無法設定;預設為 []

這個目標允許存取的目標變數集合。這些目標是規則的例項,可提供 TemplateVariableInfo,或為 Bazel 內建的工具鍊類型提供特殊目標。包括:

  • @bazel_tools//tools/cpp:current_cc_toolchain
  • @bazel_tools//tools/jdk:current_java_runtime

請注意,這與工具鍊解析的概念不同,後者是規則實作項目用於平台相關設定時所使用的概念。您無法使用這個屬性來判斷目標會使用哪個特定 cc_toolchainjava_toolchain

visibility

標籤清單;不可設定;如果已指定,則預設為package 中的 default_visibility,否則為 "//visibility:private"

目標上的 visibility 屬性會控制目標是否可用於其他套件。請參閱可見度說明文件。

所有測試規則共用的屬性 (*_test)

本節將說明所有測試規則的共同屬性。

屬性 說明
args

字串清單;會依據 $(location)"Make 變數" 替換,以及 Bourne shell 符記化;預設為 []

在使用 bazel test 執行時,Bazel 傳遞至目標的指令列引數。

這些引數會在 bazel test 指令列上指定的任何 --test_arg 值之前傳遞。

env

字串字典;值會依 $(location)「Make 變數」替換;預設為 []

指定在 bazel test 執行測試時要設定的其他環境變數。

這項屬性僅適用於原生規則,例如 cc_testpy_testsh_test。但不適用於 Starlark 定義的測試規則。針對您自己的 Starlark 規則,您可以新增「env」屬性,並用於填入 TestEnvironment 供應器。

env_inherit

字串清單;預設為 []

指定在 bazel test 執行測試時,要從外部環境繼承的其他環境變數。

這項屬性僅適用於原生規則,例如 cc_testpy_testsh_test。但不適用於 Starlark 定義的測試規則。

size

字串 "enormous""large""medium""small"不可設定;預設為 "medium"

指定測試目標的「負載程度」:執行所需的時間/資源。

單元測試被視為「小型」,整合測試為「中型」,而端對端測試則為「大型」或「超大型」。Bazel 會使用大小來決定預設逾時時間,您可以使用 timeout 屬性覆寫該值。逾時時間是針對 BUILD 目標中的所有測試,而非個別測試。在本機執行測試時,size 也會用於排程:Bazel 會嘗試遵循 --local_{ram,cpu}_resources,同時執行大量繁重測試,避免讓本機電腦不堪負荷。

測試大小對應至下列預設逾時時間和假設的本機資源使用量峰值:

大小 RAM (MB) CPU (在 CPU 核心中) 預設逾時時間
small 20 1 短 (1 分鐘)
medium 100 1 中度 (5 分鐘)
large 300 1 長 (15 分鐘)
巨大 800 1 永久 (60 分鐘)

產生測試時,環境變數 TEST_SIZE 會設為此屬性的值。

timeout

字串 "short""moderate""long""eternal"不可設定;預設值取自測試的 size 屬性

測試預計執行多久後才會傳回。

雖然測試的大小屬性可控制資源估計,但測試的逾時期限可以獨立設定。如果未明確指定,逾時時間會根據測試的大小而定。您可以使用 --test_timeout 標記覆寫測試逾時時間,例如在已知速度較慢的特定情況下執行測試。測試逾時值對應的時間範圍如下:

逾時值 時間範圍
short 1 分鐘
中度 5 分鐘
long 15 分鐘
永恆 60 分鐘

在上述時間以外,您可以使用 --test_timeout bazel 標記覆寫測試逾時時間,例如在已知速度較慢的情況下手動執行。--test_timeout 值以秒為單位。舉例來說,--test_timeout=120 會將測試逾時時間設為兩分鐘。

產生測試時,環境變數 TEST_TIMEOUT 會設為測試逾時時間 (以秒為單位)。

flaky

布林值;不可設定;預設值為 False

將測試標示為不穩定。

如果已設定,則會執行最多三次測試,且只有在每次測試都失敗時,才會將測試標示為失敗。根據預設,這項屬性會設為 False,且測試只會執行一次。請注意,一般來說,我們不建議使用這個屬性,因為在維持斷言的情況下,測試應可可靠地通過。

shard_count

小於或等於 50 的非負整數;預設值為 -1

指定用於執行測試的並行分割數量。

如果已設定,這個值會覆寫用於決定用來執行測試的平行資料分割數量的任何推論法。請注意,對於某些測試規則,您可能需要先啟用分割作業,才能使用這個參數。另請參閱 --test_sharding_strategy

如果啟用測試區塊,系統會在產生測試時將環境變數 TEST_TOTAL_SHARDS 設為這個值。

分割作業需要測試執行程式支援測試分割通訊協定。如果沒有,則很可能會在每個分割區執行每個測試,這不是您想要的結果。

如要進一步瞭解區塊,請參閱「Test Encyclopedia」中的「Test Sharding」。

local

布林值;不可設定;預設值為 False

強制在本機執行測試,不使用沙箱。

將此值設為 True 等同於提供「local」做為標記 (tags=["local"])。

所有二進位規則共用的屬性 (*_binary)

本節說明所有二進位規則的共同屬性。

屬性 說明
args

字串清單;會依據 $(location)"Make variable" 替換,以及 Bourne shell 符記化不可設定;預設值為 []

當 Bazel 透過 run 指令或測試執行目標時,會傳遞至目標的指令列引數。這些引數會在 bazel runbazel test 指令列上指定的引數之前傳遞。

注意:在 Bazel 以外執行目標時 (例如在 bazel-bin/ 中手動執行二進位檔),系統不會傳遞引數。

env

字串字典;值會根據 $(location)"Make 變數" 替換;預設值為 {}

指定在 bazel run 執行目標時要設定的其他環境變數。

這項屬性僅適用於原生規則,例如 cc_binarypy_binarysh_binary。但不適用於 Starlark 定義的可執行規則。

注意:在 Bazel 以外執行目標時 (例如,在 bazel-bin/ 中手動執行二進位檔),系統不會設定環境變數。

output_licenses

字串清單;預設為 []

這個二進位檔產生的輸出檔案授權。這是已淘汰的授權 API 的一部分,Bazel 不再使用此 API。請勿使用此選項。

可設定的屬性

大部分的屬性都是「可設定的」,也就是說,如果以不同方式建構目標,屬性值可能會有所不同。具體來說,可設定的屬性可能會因傳遞至 Bazel 指令列的旗標,或要求目標的下游依附元件而異。例如,您可以使用此方法為多個平台或編譯模式自訂目標。

以下範例會為不同的目標架構宣告不同的來源。執行 bazel build :multiplatform_lib --cpu x86 會使用 x86_impl.cc 建構目標,而替換 --cpu arm 則會導致使用 arm_impl.cc

cc_library(
    name = "multiplatform_lib",
    srcs = select({
        ":x86_mode": ["x86_impl.cc"],
        ":arm_mode": ["arm_impl.cc"]
    })
)
config_setting(
    name = "x86_mode",
    values = { "cpu": "x86" }
)
config_setting(
    name = "arm_mode",
    values = { "cpu": "arm" }
)

select() 函式會根據目標設定符合的 config_settingconstraint_value 條件,為可設定的屬性選擇不同的替代值。

Bazel 會在處理巨集後,在處理規則前評估可設定屬性 (從技術層面來說,是在 載入和分析階段之間)。select() 評估前進行的任何處理作業都不知道 select() 會選擇哪個分支。舉例來說,巨集無法根據所選分支變更行為,而 bazel query 只能對目標的可設定依附元件進行保守的預測。如要進一步瞭解如何搭配規則和巨集使用 select(),請參閱 這篇常見問題

說明文件中標示為 nonconfigurable 的屬性無法使用這項功能。通常屬性無法設定,因為 Bazel 需要先知道屬性的值,才能決定如何解析 select()

如需詳細概略說明,請參閱「 可設定的建構屬性」。

隱含輸出目標

C++ 中的隱含輸出已淘汰。請盡量避免在其他語言中使用這個字詞。我們尚未提供淘汰路徑,但這些 API 最終也會淘汰。

在 BUILD 檔案中定義建構規則時,您會在套件中明確宣告新的命名規則目標。許多建構規則函式也會隱含包含一或多個輸出檔案目標,其內容和含義則取決於規則。舉例來說,明確宣告 java_binary(name='foo', ...) 規則時,您也會隱含宣告輸出檔案目標 foo_deploy.jar 為同一個套件的成員。(這個特定目標是適合部署的獨立 Java 封存檔)。

隱含輸出目標是全域目標圖表的一流成員。就像其他目標一樣,這些目標會在需要時建構,例如在頂層建構指令中指定,或是為其他建構目標的必要先決條件。這些檔案可在 BUILD 檔案中做為依附元件參照,並可在 bazel query 等分析工具的輸出內容中觀察到。

每個建構規則的說明文件都包含一個專屬章節,詳細說明該類規則宣告所附帶的任何隱含輸出內容名稱和內容。

建構系統使用的兩個命名空間之間存在重要但略為微妙的差異:標籤可用於識別目標,這些目標可能是規則或檔案,而檔案目標可分為來源 (或輸入) 檔案目標和衍生 (或輸出) 檔案目標。這些是您可以在 BUILD 檔案中提及的項目,可透過指令列建構,或使用 bazel query 進行檢查;這是目標命名空間。每個檔案目標都會對應至磁碟上的一個實際檔案 (稱為「檔案系統命名空間」);每個規則目標可能會對應至磁碟上的零個、一個或多個實際檔案。磁碟上可能有沒有對應目標的檔案,例如在 C++ 編譯期間產生的 .o 物件檔案,無法從 BUILD 檔案或指令列中參照。如此一來,建構工具就能隱藏特定的實作細節,讓您無法得知其工作方式。詳情請參閱 BUILD 概念參考資料