常見定義

回報問題 查看來源

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

目錄

神經殼層代碼化

根據 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 依附元件通常用於讓一個模組使用在以相同程式設計語言編寫的另一個模組中定義的符號,並分開編譯。在許多情況下,也可以使用跨語言依附元件。舉例來說,在 deps 屬性中列出後者,java_library 目標可能會依附於 cc_library 目標中的 C++ 程式碼。詳情請參閱依附元件的定義。

licenses

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

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

srcs

標籤清單;預設為 []

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

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

所有建構規則通用的屬性

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

屬性 說明
compatible_with

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

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

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

deprecation

字串;不可設定;預設值為 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 屬性或 execution_requirements 的金鑰中找到任何 Starlark 動作的金鑰,藉此修改其沙箱程式碼的行為。

  • 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 等) 的擴充中排除目標,在計算用於建構/執行 buildtestcoverage 指令的頂層目標組合時,未明確列出測試的 test_suite 規則。這項設定不會影響其他結構定義中的目標萬用字元或測試套件擴充作業,包括 query 指令。請注意,manual 不表示不應由持續建構/測試系統自動建構/執行目標。舉例來說,您可能會想要從 bazel test ... 中排除目標,因為該目標需要特定的 Bazel 標記,但仍包含在正確設定的預先提交或持續測試執行作業中。
  • external 關鍵字會強制在無條件的情況下執行測試 (不論 --cache_test_results 值為何)。
請參閱測試信封中的標記慣例,進一步瞭解附加至測試目標的標記相關慣例。
target_compatible_with

標籤清單;預設為 []

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

間接依附於不相容目標的目標本身即為不相容。系統也會略過這些元素來建構和測試。

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

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

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

testonly

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

如果設為 True,則只有測試性的目標 (例如測試) 可以依附此目標。

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

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

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

由於僅供在建構時強制執行 (而非執行階段),且會透過依附元件樹狀結構傳播,因此應謹慎地套用。舉例來說,對單元測試會用到的虛設常式和假貨或許也適用於包含要發布到實際工作環境的相同二進位檔,因此可能不應標示為僅供測試用的二進位檔。相反地,若規則因無條件覆寫正常行為而危險連結,絕對應標示為僅供測試。

toolchains

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

系統允許此目標存取「Make 變數」的一組目標。這些目標不是為 Bazel 內建工具鍊類型提供 TemplateVariableInfo 的規則執行個體或特殊目標。包括:

  • @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 shell Tokenization;預設值為 []

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

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

env

字串字典;值有 $(位置)「變為變數」替換函式;預設值為 {}

指定當 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 分鐘
永恆 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 變數" 替換,以及 Bourne shell Tokenization無法設定;預設值為 []

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