常見定義

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

目錄

Bourne 殼層權杖化

某些規則中的某些字串屬性會根據 Bourne 殼層的權杖化規則分割為多個字詞:未加引號的空格分隔不同字詞,並使用單引號和雙引號字元和反斜線做為避免權杖化。

適用這項權杖化的屬性會在本文件的定義中明確指出。

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

標籤擴展

少數規則的部分字串屬性必須套用標籤:如果這些字串包含做為子字串 (例如 //mypkg:target) 的有效標籤,而該標籤是目前規則的先宣告條件,則該標籤會擴充為由 target //mypkg:target 所代表檔案的路徑名稱。

範例屬性包括 genrule.cmdcc_binary.linkopts。在每個情況下,詳細資料可能會有極大差異,像是:是否展開相對標籤、如何處理展開為多個檔案的標籤等。詳情請參閱規則屬性說明文件。

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

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

屬性 說明
data

List of labels ; optional

這項規則在執行階段所需的檔案。可以列出檔案或規則目標。通常允許任何目標。

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

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

deps

List of labels ; optional

這個目標的依附元件。通常應該只列出規則目標。(雖然部分規則允許檔案直接列於 deps 中,但請盡量避免這種情況。)

語言專屬規則通常只會將列出的目標限制在具有特定提供者的使用者。

使用 deps 時,目標互相依賴的語意意義就在於規則種類,而規則專屬的說明文件將詳細說明。對於會處理原始碼的規則,deps 通常會指定 srcs 中程式碼使用的程式碼依附元件。

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

licenses

List of strings; optional; nonconfigurable

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

srcs

List of labels ; optional

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

語言專屬的規則通常需要列出的檔案副檔名。

所有建構規則通用的屬性

本節說明以隱含方式新增到所有建構規則的屬性。

屬性 說明
compatible_with

List of labels ; optional; nonconfigurable

除了預設支援的環境之外,您還可以建立此目標的環境清單。

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

deprecation

String; optional; nonconfigurable

與這個目標相關的說明警告訊息。 通常用於通知使用者目標已過時、遭到其他規則取代、僅供套件使用,或可能基於某些原因而被視為有害。建議您加入一些參考資料 (例如網頁、錯誤編號或遷移 CL 範例),方便員工瞭解收到訊息前需要哪些變更,才能避免收到相關訊息。如果有新的目標可做為替換用的新目標,建議您只遷移舊目標的所有使用者。

這項屬性不會影響項目的建構方式,但可能會影響建構工具的診斷輸出內容。當具有 deprecation 屬性的規則受到另一個套件中的目標相關時,建構工具會發出警告。

套件內依附元件不受這項警告影響,因此,即使建構已淘汰規則的測試,也不會收到警告。

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

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

distribs

List of strings; optional; nonconfigurable

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

exec_compatible_with

List of labels ; optional; nonconfigurable

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

exec_properties

Dictionary of strings; optional

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

如果平台和目標層級屬性中都存在一個鍵,系統會從目標中擷取該值。

features

List of feature strings; optional

功能是可在目標中啟用或停用的字串標記。特徵的意義會因規則本身而異。

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

restricted_to

List of labels ; optional; nonconfigurable

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

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

tags

List of strings; optional; nonconfigurable

標記可用於任何規則。測試上的標記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 會強制以「專屬」模式執行測試;但如果是在遠端執行,則會同時執行測試。
  • manual 關鍵字會排除目標,防止目標模式萬用字元 (...:*:all 等) 的擴充,以及 test_suite 規則在為 buildtestcoverage 指令計算頂層目標組合時未明確列出測試。但不會影響其他情況 (包括 query 指令) 目標萬用字元或測試套件擴充。請注意,manual 不暗示不得由持續建構/測試系統自動建構/執行目標。舉例來說,您或許可以從 bazel test ... 中排除目標,因為該目標需要特定的 Bazel 標記,卻仍包含在設定的預先提交或持續測試執行作業中。
  • external 關鍵字會強制一律執行測試 (無論 --cache_test_results 值為何)。
請參閱測試百科全書中的標記慣例一文,進一步瞭解附加至測試目標的標記慣例。
target_compatible_with

List of labels ; optional

必須出現在目標平台中的 constraint_value 清單,系統才會將這個目標視為相容。除了規則類型已設定的任何限制外,您也要注意。如果目標平台無法滿足所有列出的限制,系統就會將目標視為「不相容」incompatible。系統會在展開目標模式 (例如 //...:all) 時略過不相容的目標,以便進行建構及測試。如果在指令列上明確指定不相容的目標,則會導致 Bazel 列印錯誤,並導致建構或測試失敗。

會間接依附於不相容目標的目標本身會視為不相容。建構及測試時也會略過這些測試。

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

工作區規則以外的所有規則都支援這項屬性。對部分規則而言,這個屬性不會有任何作用。舉例來說,為 cc_toolchain 指定 target_compatible_with 並不實用。

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

testonly

Boolean; optional; default False except for test and test suite targets; nonconfigurable

如果為 True,則只有測試專用的目標 (例如測試) 可以依附這個目標。

同樣地,非 testonly 的規則也不得依附於任何為 testonly 的規則。

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

這個屬性的用途是目標不應包含在已發布至正式版的二進位檔中。

由於測試只會在建構時間強制執行,而非執行階段,並且會透過依附元件樹狀結構傳播,因此您應審慎套用。舉例來說,適用於單元測試的虛設常式和假造可能也很有幫助,涉及的整合測試涉及將發布至實際工作環境的相同二進位檔,因此不應標示為測試專用。相反地,如果規則即使連進來危險,可能就應該標示為「僅供測試」,或許因為它們會無條件覆寫正常行為。

toolchains

List of labels ; optional; nonconfigurable

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

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

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

visibility

List of labels ; optional; default default_visibility from package if specified, or //visibility:private otherwise; nonconfigurable

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

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

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

屬性 說明
args

List of strings; optional; subject to $(location) and "Make variable" substitution, and Bourne shell tokenization

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

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

env

Dictionary of strings; optional; values are subject to $(location) and "Make variable" substitution

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

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

env_inherit

List of strings; optional

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

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

size

String "enormous", "large" "medium" or "small", default is "medium"; optional; nonconfigurable

指定測試目標的「核心」:執行需要多少時間/資源。

單元測試屬於「小」,整合測試為「中」,端對端測試則為「大」或「龐大」。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

String "short", "moderate", "long", "eternal" (with the default derived from the test's size attribute); nonconfigurable

在傳回前執行測試的預期時間長度。

雖然測試的大小屬性會控制資源估算,但測試的逾時功能可以獨立設定。如果未明確指定,逾時時間會以測試的大小為依據。您可以使用 --test_timeout 旗標覆寫測試逾時,例如在已知的執行速度緩慢的情況下執行。測試逾時值對應下列時間範圍:

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

針對以上情況以外的時間,您可以使用 --test_timeout Bazel 標記覆寫測試逾時,例如適用於在已知緩慢情況下手動執行。--test_timeout 值以秒為單位。例如,--test_timeout=120 會將測試逾時設為兩分鐘。

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

flaky

Boolean; optional; default False; nonconfigurable

將測試標示為不穩定。

如果已設定,可執行測試最多三次,只有在每次都失敗時才會將其標示為失敗。這項屬性的預設值為 False,且測試只會執行一次。請注意,我們一般不建議使用此屬性;如果測試保留,就應該可靠地通過測試。

shard_count

Non-negative integer less than or equal to 50; optional

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

這個值會覆寫任何經驗法則,用於決定用於執行測試的平行資料分割數量。請注意,在某些測試規則中,一開始可能需要這個參數才能啟用資料分割。另請參閱 --test_sharding_strategy

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

如要進行資料分割,測試執行器必須支援測試資料分割通訊協定。如果不是的話,很有可能會在每個資料分割中執行每項測試,這並非您要的結果。

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

local

Boolean; default False; nonconfigurable

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

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

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

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

屬性 說明
args

List of strings; optional; subject to $(location) and "Make variable" substitution, and Bourne shell tokenization; nonconfigurable

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

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

env

Dictionary of strings; optional; values are subject to $(location) and "Make variable" substitution

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

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

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

output_licenses

List of strings; optional

這個二進位檔產生的輸出檔案授權。這是 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 檔案或指令列參照。如此一來,建構工具可能會隱藏特定工作方式的實作詳細資料。詳情請參閱 BUILD 概念參考資料