常見定義

回報問題 查看來源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

目錄

Bourne Shell 權杖化

根據 Bourne Shell 的權杖化規則,部分規則的特定字串屬性會分割成多個字詞:未加引號的空格會分隔字詞,單引號、雙引號和反斜線字元則會防止權杖化。

凡是會經過權杖化的屬性,都會在本文件的定義中明確指出。

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

標籤擴展

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

例如 genrule.cmdcc_binary.linkopts。在每個案例中,詳細資料可能會有顯著差異,例如相對標籤是否會展開、展開為多個檔案的標籤如何處理等。如需具體細節,請參閱規則屬性說明文件。

大多數建構規則定義的典型屬性

本節說明許多 (但並非所有) 建構規則定義的屬性。

屬性 說明
data

標籤清單;預設值為 []

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

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

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

deps

標籤清單;預設值為 []

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

一般來說,語言專屬規則會將列出的目標限制為具有特定供應商的目標。

目標依附於另一個目標的確切語意 (使用 deps),取決於規則類型,規則專屬文件會提供更詳細的說明。對於處理原始碼的規則,deps 通常會指定 srcs 中程式碼使用的程式碼依附元件。

在大多數情況下,deps 依附元件是用來讓一個模組使用以相同程式設計語言編寫,並個別編譯的另一個模組中定義的符號。在許多情況下,系統也允許跨語言依附元件:舉例來說,java_library 目標可能會依附於 cc_library 目標中的 C++ 程式碼,方法是在 deps 屬性中列出後者。詳情請參閱依附元件的定義。

licenses

字串清單;無法設定; 預設為 ["none"]

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

srcs

標籤清單;預設值為 []

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

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

所有建構規則通用的屬性

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

屬性 說明
aspect_hints

標籤清單;預設值為 []

任意標籤清單,會公開給層面 (特別是這個規則的反向依附元件所叫用的層面),但不會公開給這個規則本身的實作項目。如要瞭解特定長寬比提示的效果,請參閱語言專屬規則集的說明文件。

您可以將方面提示視為 標記的進階替代方案: 標記只會傳達布林狀態 (標記存在於 tags 清單中或不存在),方面提示則可在 providers 中傳達任意結構化資訊。

在實務上,層面提示用於不同語言專屬規則集之間的互通性。舉例來說,假設您有一個 mylang_binary 目標,需要依附於 otherlang_library 目標。MyLang 專屬邏輯需要 OtherLang 目標的其他資訊才能使用,但 otherlang_library 不提供這項資訊,因為它對 MyLang 一無所知。其中一種解決方法可能是讓 MyLang 規則集定義 mylang_hint 規則,用於編碼額外資訊;使用者可以在 otherlang_libraryaspect_hints 中新增提示,而 mylang_binary 可以使用構面,從 mylang_hint 中 MyLang 專屬的供應商收集額外資訊。

如需具體範例,請參閱 rules_swift 中的 swift_interop_hintswift_overlay

最佳做法:

  • aspect_hints 中列出的目標應輕省且盡量減少。
  • 語言專屬邏輯應只考量與該語言相關的供應商所提供的層面提示,並忽略任何其他層面提示。
compatible_with

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

這個目標可建構的環境清單,以及預設支援的環境。

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

deprecation

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

與這個目標相關的說明警告訊息。 通常用於通知使用者目標已過時、已被其他規則取代、屬於套件的私有目標,或可能因某種原因被視為有害。建議您加入一些參考資料 (例如網頁、錯誤編號或遷移 CL 範例),方便使用者輕鬆找出避免顯示訊息所需的變更。如果有新的目標可做為替代方案,建議直接遷移舊目標的所有使用者。

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

套件內依附元件可免除這項警告,因此舉例來說,建構已淘汰規則的測試時,不會遇到警告。

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

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

exec_compatible_with

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

constraint_values 清單,必須存在於這個目標預設執行群組的執行平台中。這項限制會與規則類型已設定的限制一併生效。 限制可用執行平台清單。 詳情請參閱工具鍊解析的說明。和 執行群組

exec_group_compatible_with

字串字典,對應至 labels 清單; nonconfigurable;預設為 {}

執行群組名稱的字典,對應至特定執行群組的執行平台中必須存在的 constraint_values 清單。除了已在執行群組定義中設定的任何限制外,限制可用執行平台清單。 詳情請參閱工具鍊解析的說明。和 執行群組

exec_properties

字串字典,預設為 {}

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

如果平台和目標層級屬性都有鍵,系統會採用目標的值。

鍵可以加上執行群組的名稱做為前置字元,後面加上 .,這樣鍵就只會套用至該特定執行群組。

features

功能字串清單;預設值為 []

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

這項 features 屬性會與 套件層級的 features 屬性合併。舉例來說,如果套件層級已啟用 ["a", "b"] 功能,且目標的 features 屬性包含 ["-a", "c"],則規則啟用的功能會是「b」和「c」。 查看範例

package_metadata

標籤清單; 不可設定;預設值為套件的 default_package_metadata

與這個目標相關聯的中繼資料標籤清單。 通常標籤是簡單的規則,會傳回常數值的供應商。規則和層面可能會使用這些標籤,對建構圖表執行一些額外分析。

標準用途是 rules_license。在該用途中,package_metadatadefault_package_metadata 用於將套件授權或版本資訊附加至目標。套用至頂層二進位的層面可用於收集這些資訊,並產生法規遵循報表。

restricted_to

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

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

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

tags

字串清單;無法設定; 預設為 []

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

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

  • no-sandbox 關鍵字會導致動作或測試永遠不會進入沙箱;動作或測試仍可快取或遠端執行 - 使用 no-cacheno-remote 可防止其中一項或兩項操作。
  • no-cache 關鍵字,導致動作或測試永遠不會快取 (在本機或遠端)。注意:就這個標記而言,磁碟快取視為本機快取,而 HTTP 和 gRPC 快取則視為遠端快取。其他快取 (例如 Skyframe 或持續性動作快取) 不受影響。
  • no-remote-cache 關鍵字,導致動作或測試永遠不會從遠端快取 (但可能會在本機快取;也可能會從遠端執行)。注意:就這個標記而言,磁碟快取視為本機快取,而 HTTP 和 gRPC 快取則視為遠端快取。其他快取 (例如 Skyframe 或持續性動作快取) 不受影響。如果同時使用本機磁碟快取和遠端快取 (合併快取),系統會將其視為遠端快取,並完全停用,除非已設定 --incompatible_remote_results_ignore_disk,否則系統會使用本機元件。
  • no-remote-exec 導致動作或測試永遠不會從遠端執行 (但可能會從遠端快取)。
  • no-remote 關鍵字可防止動作或測試從遠端執行或從遠端快取。這相當於同時使用 no-remote-cacheno-remote-exec
  • no-remote-cache-upload 關鍵字會停用衍生項遠端快取的上傳部分。 不會停用遠端執行作業。
  • local 關鍵字會禁止從遠端快取、從遠端執行動作或測試,或在沙箱中執行動作或測試。對於 genrule 和測試,使用 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 會強制測試在本機執行時採用「專屬」模式,但如果是在遠端執行,則會平行執行測試。
  • manual 關鍵字會將目標從目標模式萬用字元 (...:*:all 等) 和 test_suite 規則的擴展中排除,這些規則在計算要為 buildtestcoverage 指令建構/執行的頂層目標集時,不會明確列出測試。這項變更不會影響其他情境中的目標萬用字元或測試套件擴充功能,包括 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:toolchain_type
  • @rules_java//toolchains:current_java_runtime

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

visibility

標籤清單; 無法設定; 預設值因標籤而異

visibility 屬性可控制其他位置的目標是否能依附目標。請參閱可見度說明文件。

如果是直接在 BUILD 檔案中宣告的目標,或是從 BUILD 檔案呼叫的舊版巨集,預設值為套件的 default_visibility (如有指定),否則為 ["//visibility:private"]。對於在一或多個符號巨集中宣告的目標,預設值一律為 ["//visibility:private"] (這表示只能在包含巨集程式碼的套件中使用)。

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

本節說明所有測試規則通用的屬性。

屬性 說明
args

字串清單;須遵守 $(location) 和「建立變數」替代,以及 Bourne Shell 權杖化;預設為 []

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

這些引數會先傳遞,再傳遞 bazel test 指令列上指定的任何 --test_arg 值。

env

字串字典;值須符合 $(location) 和「Make variable」(建立變數) 替代項目;預設值為 {}

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

這項屬性僅適用於原生規則,例如 cc_testpy_testsh_test。這項功能不適用於 Starlark 定義的測試規則。如果是您自己的 Starlark 規則,可以新增「env」屬性,並用來填入 RunEnvironmentInfo Provider。

TestEnvironment Provider.

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 屬性

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

測試的 size 屬性會控管資源預估,但測試的逾時時間可以獨立設定。如果未明確指定,逾時時間會根據測試大小而定。您可以使用 --test_timeout 標記覆寫測試逾時,例如在已知速度緩慢的特定條件下執行測試。測試逾時值對應的時間範圍如下:

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

如需其他時間,可以使用 --test_timeout bazel 旗標覆寫測試逾時,例如在已知速度緩慢的條件下手動執行。--test_timeout 值以秒為單位。舉例來說,--test_timeout=120 會將測試逾時時間設為兩分鐘。

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

flaky

布林值;無法設定; 預設值為 False

將測試標示為不穩定。

如果設定此選項,系統最多會執行三次測試,只有在每次測試都失敗時,才會將測試標示為失敗。根據預設,這項屬性會設為 False,且測試只會執行一次。請注意,一般不建議使用這項屬性,因為測試應在斷言成立時可靠地通過。

shard_count

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

指定要用於執行測試的平行分片數量。

如果設定這個值,系統會覆寫所有用來判斷平行資料分割數量的啟發式方法,並以這個值執行測試。請注意,部分測試規則可能需要這個參數,才能啟用分片。另請參閱 --test_sharding_strategy

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

資料分割需要測試執行器支援測試資料分割通訊協定。 如果沒有,系統很可能會在每個分片中執行所有測試,這並非您所要的結果。

如要瞭解分片作業的詳細資訊,請參閱測試百科全書中的「測試分片」。

local

布林值;無法設定; 預設值為 False

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

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

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

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

屬性 說明
args

字串清單;須遵守 $(location) 和「Make variable」(建立變數) 替代項目,以及 Bourne shell 權杖化無法設定;預設為 []

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

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

env

字串字典;值須符合 $(location) 和「Make variable」(建立變數) 替代項目;預設值為 {}

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

這項屬性僅適用於原生規則,例如 cc_binarypy_binarysh_binary。這不適用於 Starlark 定義的可執行規則。如果是您自己的 Starlark 規則,可以新增「env」屬性,並用來填入 RunEnvironmentInfo Provider。

注意:在 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 檢查;這是目標命名空間。每個檔案目標都對應至磁碟上的一個實際檔案 (「檔案系統命名空間」);每個規則目標可能對應至磁碟上的零個、一個或多個實際檔案。磁碟上可能會有沒有對應目標的檔案;舉例來說,從 BUILD 檔案或指令列中,無法參照 C++ 編譯期間產生的 .o 物件檔案。這樣一來,建構工具可能會隱藏其工作方式的特定實作細節。詳情請參閱「BUILD 概念參考資料」。