常見定義

回報問題

本節定義許多函式或建構規則通用的詞彙和概念。

目錄

Bourne 殼層權杖化

某些規則的特定字串屬性,會根據 Bourne 殼層的代碼化規則分成多個字詞:未加引號的空格分隔每個字詞,以及使用單引號和雙引號字元和反斜線,用於避免代碼化。

這類代碼化的屬性會在本文件中的定義中明確表示。

受到「Make」變數擴充和 Bourne 殼層權杖化的屬性通常是用於將任意選項傳送至編譯器和其他工具。這類屬性的例子包括 cc_library.coptsjava_library.javacopts。這些替代變數可讓單一字串變數展開為設定專屬的選項字詞清單。

標籤擴展

只有極少數規則的字串屬性會受到標籤擴充:如果這些字串包含做為子字串的有效標籤 (例如 //mypkg: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"]

要用於此特定目標的授權類型字串清單。這是 Bazel 不再使用的授權 API 的一部分。請勿使用此屬性。

srcs

標籤清單;預設值為 []

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

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

所有建構規則通用的屬性

本節說明自動新增至所有建構規則的屬性。

屬性 說明
compatible_with

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

除了預設支援的環境之外,也可以建構這個目標的環境清單。

這是 Bazel 限制系統的一部分,可讓使用者宣告哪些目標可以彼此依附。例如,外部可部署的二進位檔不應仰賴含有公司秘密程式碼的程式庫。詳情請參閱 ConstraintSemantics

deprecation

字串;nonconfigurable;預設值為 None

與這個目標相關的說明警告訊息。通常用途是通知使用者目標已過時或已由其他規則取代、套件私有,或因某些原因而被視為有害。建議您納入一些參考資料 (例如網頁、錯誤編號或遷移 CL 範例),方便相關人員瞭解必須進行哪些變更才能避免訊息。如果有一個新目標可用做取代,建議您只遷移舊目標的所有使用者。

這個屬性對建構方式沒有影響,但可能會影響建構工具的診斷輸出內容。當具有 deprecation 屬性的規則依其他套件中的目標而定,建構工具會發出警告。

內部套件依附元件不受此警告的約束,因此舉例來說,為已淘汰的規則建構測試時,系統不會發出警告。

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

一旦使用者停止使用,即可移除目標。

distribs

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

這個特定目標要使用的發布方法字串清單。這是 Bazel 不再使用的授權 API 的一部分。請勿使用此屬性。

exec_compatible_with

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

執行平台中必須含有這個目標的 constraint_values 清單。這項特性不適用於已由規則類型設定的任何限制。限制用於限制可用執行平台的清單。詳情請參閱工具鍊解決方案的說明。

exec_properties

字串字典;預設值為 {}

字串字典,會新增至為這個目標選擇的平台的 exec_properties。請參閱平台規則的 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 關鍵字會禁止在沙箱中存取外部網路。在這種情況下,只能與 localhost 通訊。只有在啟用沙箱功能時,這個標記才會生效。
  • requires-fakeroot 會以 uid 和 gid 0 (即根使用者) 的身分執行測試或動作。這項功能僅適用於 Linux。這個標記的優先順序高於 --sandbox_fake_username 指令列選項。

測試上的標記通常用於在偵錯和發布程序中為測試的角色加上註解。一般來說,標記最適合用於 C++ 和 Python 測試,因為這類測試沒有任何執行階段註解功能。使用標記和大小元素可讓您根據程式碼集檢查政策,靈活組合測試套件。

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

  • exclusive 會強制在「專屬」模式下執行測試,確保不會同時執行其他測試。等所有建構活動及非專屬的測試完成後,這類測試就會依序執行。由於 Bazel 無法控管遠端電腦執行的內容,因此已停用這類測試的遠端執行功能。
  • 如果測試在本機執行,exclusive-if-local 會強制以「專屬」模式執行測試,但如果是在遠端執行,則會平行執行測試。
  • 在計算 buildtestcoverage 指令時,manual 關鍵字會排除目標模式萬用字元 (...:*:all 等) 的擴充目標,以及未明確列出該測試的 test_suite 規則。在其他情況下,包括 query 指令在內的目標萬用字元或測試套件擴充功能不會受到影響。請注意,manual 不表示不是由持續建構/測試系統自動建構/執行目標。舉例來說,假設您希望從 bazel test ... 中排除目標,因為這個目標需要特定的 Bazel 旗標,但仍包含在正確設定的預先提交或持續測試執行中。
  • external 關鍵字會強制在無條件地執行測試 (不論 --cache_test_results 值為何)。
如需進一步瞭解對測試目標附加標記的慣例,請參閱測試百科全書中的「標記慣例」。
target_compatible_with

標籤清單;預設值為 []

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

系統會將間接依賴不相容的目標視為不相容的目標。建構和測試時也會略過這些函式。

如果清單是空白清單 (預設值),代表目標與所有平台相容。

Workspace 規則以外的所有規則都支援這個屬性。對某些規則而言,這個屬性不會有任何作用。例如,為 cc_toolchain 指定 target_compatible_with 並不實用。

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

testonly

布林值;nonconfigurable;預設為 False (測試和測試套件目標除外)

如果設為 True,則只有測試專用的目標 (例如測試) 能夠依賴這個目標。

等同於不允許 testonly 的規則依附任何 testonly 規則。

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

這項屬性旨在意味著,目標不應包含在發布至正式版的二進位檔中。

由於測試專用範圍是在建構期間 (而非執行階段) 強制執行,並且會透過依附元件樹狀結構傳播,因此應謹慎地套用。舉例來說,在涉及要發布至實際工作環境的相同二進位檔的整合測試中,實用的虛設常式和虛構資料或許也很有用,因此可能不應標記為測試。反之,即使規則無條件覆寫到正常行為,也對這類規則而言具有危險性,因此絕對應標示為僅限測試。

toolchains

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

允許這個目標存取的「建立變數」目標組合。這些目標可能是提供 TemplateVariableInfo 的規則執行個體,或是為 Bazel 內建的工具鍊類型提供特殊目標。包括:

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

請注意,這與工具鍊解決方案的概念不同 (後者用於平台相依設定的規則實作)。您無法使用這項屬性來確定目標會使用哪一個 cc_toolchainjava_toolchain

visibility

標籤清單;不可設定;預設值為 套件中的 default_visibility,否則為 "//visibility:private"

目標的 visibility 屬性可控管目標能否在其他套件中使用。如要瞭解瀏覽權限,請參閱瀏覽權限說明文件。

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

本節說明所有測試規則的常見屬性。

屬性 說明
args

字串清單;取決於 $(location)"Make 變數" 替換,以及 Bourne 殼層權杖化;預設值為 []

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

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

env

字串字典;值適用 $(location)"MakeVariable" 替換,預設值為 []

指定 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 分鐘)
媒介 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 分鐘
Eternal 60 分鐘

如果不是上述情況,則可使用 --test_timeout bazel 標記覆寫測試逾時,例如在已知緩慢的情況下手動執行。--test_timeout 值以秒為單位。例如,--test_timeout=120 會將測試逾時設為兩分鐘。

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

flaky

布林值;nonconfigurable;預設值為 False

將測試標示為「flaky」。

如果設定的話,最多會執行測試三次;只有在每次測試失敗時才標示為失敗。根據預設,此屬性設為 False,且測試只會執行一次。請注意,一般不建議使用這項屬性,測試在維持其斷言時,應能夠穩定通過測試。

shard_count

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

指定用於執行測試的平行資料分割數量。

設定後,這個值將覆寫用於決定執行測試的平行資料分割數量的任何經驗法則。請注意,對於某些測試規則,您可能需要此參數才能先啟用資料分割。另請參閱 --test_sharding_strategy

如果測試資料分割已啟用,系統會在產生測試時將環境變數 TEST_TOTAL_SHARDS 設為這個值。

資料分割需要測試執行器支援測試資料分割通訊協定。如果不是的話,系統很可能會在每個資料分割中執行所有測試,而這並非您想要的情況。

如要進一步瞭解資料分割,請參閱測試百科全書中的「測試資料分割」。

local

布林值;nonconfigurable;預設值為 False

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

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

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

本節說明所有二進位規則通用的屬性。

屬性 說明
args

字串清單;取決於 $(location)"Make variant" 替代形式,以及 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

字串清單;預設值為 []

這個二進位檔產生的輸出檔案授權。 這是 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++ 中的隱式輸出內容已淘汰,請盡量避免用於其他語言。我們目前並沒有淘汰路徑,但最終也會淘汰。

在 BUILD 檔案中定義建構規則時,您必須在套件中明確宣告新的已命名規則目標。許多建構規則函式還「間接」包含一或多個輸出檔案目標,其內容與意義會因規則而異。舉例來說,當您明確宣告 java_binary(name='foo', ...) 規則時,也會「間接」將輸出檔案的目標 foo_deploy.jar 宣告為同一套件的成員。(這項特殊目標是適合部署的獨立 Java 封存檔)。

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

每種建構規則的說明文件都包含特殊區段,當中詳細說明任何隱含輸出的名稱和內容,其中必須包含該類規則的宣告。

建構系統使用的兩個命名空間之間有幾項重要但有些微差異:標籤可用來識別「目標」 (可以是規則或檔案),而檔案目標則可分成來源 (或輸入) 檔案目標,以及衍生 (或輸出) 檔案目標。這些是您可以在 BUILD 檔案中提及的內容、透過指令列建構,或使用 bazel query 進行檢查;這就是「目標命名空間」。每個檔案目標都會對應到磁碟上的一個實際檔案 (「檔案系統命名空間」)。每個規則目標都可能對應到零個或多個磁碟中的實際檔案。磁碟中可能有檔案沒有相應的目標;舉例來說,C++ 編譯期間產生的 .o 物件檔案無法透過 BUILD 檔案或指令列參照。如此一來,建構工具可能會隱藏某些實作詳細資料,以致於無法執行其工作。如要進一步瞭解相關資訊,請參閱「建構概念參考資料」一文。