規則
別名
查看規則來源alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
alias 規則會建立另一個規則可參照的名稱。
別名只適用於「一般」目標。具體來說,package_group 和 test_suite 無法使用別名。
在大型存放區中,如果要變更目標,就必須變更大量檔案,這時使用別名可能會有所幫助。如果您想為多個目標重複使用該邏輯,也可以使用別名規則來儲存 select 函式呼叫。
別名規則有其專屬的顯示宣告。在其他方面,它會像參照的規則一樣運作 (例如,系統會忽略別名上的 testonly,改為使用參照規則的 testonly 屬性),但有些小例外狀況除外:
-
如果指令列中提到別名,系統就不會執行測試。如要定義執行參照測試的別名,請使用
test_suite規則,並在其tests屬性中加入單一目標。 -
定義環境群組時,系統不支援
environment規則的別名。--target_environment指令列選項也不支援這些功能。
範例
filegroup(
name = "data",
srcs = ["data.txt"],
)
alias(
name = "other",
actual = ":data",
)
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
actual
|
標籤;必填 這個別名所參照的目標。不必是規則,也可以是輸入檔案。 |
config_setting
查看規則來源config_setting(name, constraint_values, define_values, deprecation, distribs, features, flag_values, licenses, tags, testonly, values, visibility)
與預期的設定狀態相符 (以建構標記或平台限制表示),以便觸發可設定的屬性。如要瞭解如何使用此規則,請參閱「選取」一文,並參閱「 可設定屬性」一文,瞭解一般功能的總覽。
範例
以下會比對任何設定 --compilation_mode=opt 或 -c opt 的建構作業 (無論是在指令列中明確設定,或是在 .bazelrc 檔案中隱含設定):
config_setting(
name = "simple",
values = {"compilation_mode": "opt"}
)
以下內容會比對任何以 ARM 為目標的版本,並套用自訂定義 FOO=bar (例如 bazel build --cpu=arm --define FOO=bar ...):
config_setting(
name = "two_conditions",
values = {
"cpu": "arm",
"define": "FOO=bar"
}
)
以下內容會比對任何設定 使用者定義的標記
--//custom_flags:foo=1 的建構作業 (無論是在指令列中明確設定,或是在 .bazelrc 檔案中隱含設定):
config_setting(
name = "my_custom_flag_is_set",
flag_values = { "//custom_flags:foo": "1" },
)
以下內容會比對任何以 x86_64 架構和 glibc 2.25 版為目標的平台為目標的版本,假設存在標示為 //example:glibc_2_25 的 constraint_value。請注意,如果平台定義了上述兩個限制值以外的其他限制值,仍會符合條件。
config_setting(
name = "64bit_glibc_2_25",
constraint_values = [
"@platforms//cpu:x86_64",
"//example:glibc_2_25",
]
)
config_setting 不符合頂層指令列標記,仍可能符合部分建構目標。附註
- 如要瞭解多個
config_setting與目前設定狀態相符時會發生什麼事,請參閱「選取」。 - 對於支援簡寫形式的旗標 (例如
--compilation_mode與-c),values定義必須使用完整形式。這些自動比對會使用任一形式的叫用作業。 -
如果標記採用多個值 (例如
--copt=-Da --copt=-Db或清單型 Starlark 標記),values = { "flag": "a" }會在實際清單的任何位置出現"a"時相符。values = { "myflag": "a,b" }的運作方式相同:這會比對--myflag=a --myflag=b、--myflag=a --myflag=b --myflag=c、--myflag=a,b和--myflag=c,b,a。旗標的確切語意因旗標而異。舉例來說,--copt不支援在同一個例項中使用多個值:--copt=a,b會產生["a,b"],而--copt=a --copt=b會產生["a", "b"](因此values = { "copt": "a,b" }會比對前者,但不會比對後者)。但--ios_multi_cpus(適用於 Apple 規則) 會:-ios_multi_cpus=a,b和ios_multi_cpus=a --ios_multi_cpus=b都會產生["a", "b"]。請檢查標記定義,並仔細測試條件,確認實際預期結果。 - 如果您需要定義內建建構標記無法模擬的條件,請使用
Starlark 定義的標記。您也可以使用
--define,但這項功能的支援程度較低,因此不建議使用。詳情請參閱這篇文章。 - 避免在不同套件中重複相同的
config_setting定義。請改為參照標準套件中定義的常見config_setting。 values、define_values和constraint_values可在同一個config_setting中以任何組合使用,但每個config_setting至少必須設定一個。
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
constraint_values
|
目標平台必須指定的 constraint_values 最低組合,才能符合這個 config_setting。(這裡不考量執行平台)。平台的任何其他限制值都會遭到忽略。詳情請參閱「
可設定的建構屬性」。如果兩個 如果兩個 |
define_values
|
字典:字串 -> 字串;不可設定;預設為 values 相同,但專門用於 --define 標記。
也就是說:
config_setting(
name = "a_and_b",
values = {
"define": "a=1",
"define": "b=2",
})
因為字典中出現了相同的鍵 (
config_setting(
name = "a_and_b",
define_values = {
"a": "1",
"b": "2",
})
正確比對
|
flag_values
|
與 values 相同,但適用於
使用者定義的建構標記。這是一個獨特的屬性,因為使用者定義的旗標會以標籤的形式參照,而內建旗標會以任意字串的形式參照。 |
values
|
字典:字串 -> 字串;不可設定;預設為 這個規則會繼承已設定目標的設定,該目標會在 為方便起見,設定值會指定為建構標記 (不含前置 如果在指令列中未明確設定標記,系統會使用預設值。如果字典中出現多個相同的鍵,系統只會使用最後一個。如果鍵參照的標記可以在指令列上多次設定 (例如
|
filegroup
查看規則來源filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, restricted_to, tags, target_compatible_with, testonly, visibility)
使用 filegroup 收集單一標籤下的一組目標輸出內容。
filegroup 並非在指令列或其他規則的屬性中列出目標的替代方案,因為目標除了輸出內容外,還有許多屬性,這些屬性並未以相同方式收集。不過,在某些情況下,這項功能仍相當實用,例如在 genrule 的 srcs 屬性,或 *_binary 規則的 data 屬性中。
建議您使用 filegroup,而非直接參照目錄。我們不建議直接參照目錄,因為建構系統無法完全瞭解目錄下方的所有檔案,因此可能不會在這些檔案變更時重新建構。搭配使用 glob 時,filegroup 可確保建構系統明確知道所有檔案。
範例
如要建立包含兩個來源檔案的 filegroup,請執行以下操作:
filegroup(
name = "mygroup",
srcs = [
"a_file.txt",
"//a/library:target",
"//a/binary:target",
],
)
或者,您也可以使用 glob 全面檢索 testdata 目錄:
filegroup(
name = "exported_testdata",
srcs = glob([
"testdata/*.dat",
"testdata/logs/**/*.log",
]),
)
如要使用這些定義,請在任何規則中使用標籤參照 filegroup:
cc_library(
name = "my_library",
srcs = ["foo.cc"],
data = [
"//my_package:exported_testdata",
"//my_package:mygroup",
],
)
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
srcs
|
標籤清單;預設為
通常會將 glob 運算式的結果用於 |
data
|
標籤清單;預設為
|
output_group
|
字串;預設為 「輸出群組」是目標的輸出構件類別,由規則的實作項目指定。 |
genquery
查看規則來源genquery(name, deps, data, compatible_with, compressed_output, deprecation, distribs, exec_compatible_with, exec_properties, expression, features, licenses, opts, restricted_to, scope, strict, tags, target_compatible_with, testonly, visibility)
genquery() 會執行 Bazel 查詢語言中指定的查詢,並將結果轉儲至檔案。
為了維持建構作業的一致性,查詢只能造訪 scope 屬性中指定目標的傳遞閉包。如果 strict 未指定或為 true,違反此規則的查詢會在執行期間失敗 (如果 strict 為 false,系統會略過超出範圍的目標,並顯示警告)。如要確保不會發生這種情況,最簡單的方法是在範圍中提及與查詢運算式相同的標籤。
這裡允許的查詢與指令列允許的查詢唯一的差異在於,這裡不允許包含萬用字元目標規範 (例如 //pkg:* 或 //pkg:all) 的查詢。原因有兩個:首先,genquery 必須指定範圍,以免查詢的傳遞閉包以外的目標影響其輸出結果;其次,BUILD 檔案不支援萬用字元依附元件 (例如不允許 deps=["//a/..."])。
為了強制產生確定性的輸出內容,genquery 的輸出內容會依字典順序排序,但 --output=graph|minrank|maxrank 或 somepath 用於頂層函式時除外。
輸出檔案的名稱即為規則名稱。
範例
這個範例會將指定目標的傳遞閉包中標籤清單寫入檔案。
genquery(
name = "kiwi-deps",
expression = "deps(//kiwi:kiwi_lib)",
scope = ["//kiwi:kiwi_lib"],
)
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
compressed_output
|
布林值;預設值為 True,查詢輸出內容會以 GZIP 檔案格式寫入。這項設定可用於避免在查詢輸出預期會很大時,Bazel 記憶體用量突然激增。無論這項設定的值為何,Bazel 已在內部壓縮大於 220 位元組的查詢輸出內容,因此將此值設為 True 可能不會減少保留堆積。不過,這會讓 Bazel 在寫入輸出檔案時略過解壓縮作業,而這項作業可能會耗用大量記憶體。 |
expression
|
字串;必填 要執行的查詢。與指令列和 BUILD 檔案中的其他位置不同,此處的標籤會相對於工作區的根目錄進行解析。舉例來說,檔案a/BUILD 中這個屬性的標籤 :b 會參照目標 //:b。 |
opts
|
字串清單;預設為 bazel query 的指令列選項。以下查詢選項不在此處允許:--keep_going、--query_file、--universe_scope、--order_results 和 --order_output。如未在此處指定選項,則會採用預設值,就像在 bazel query 的指令列上一樣。 |
scope
|
標籤清單 (必要) 查詢範圍。查詢不得觸及這些目標的傳遞閉包以外的目標。 |
strict
|
布林值;預設值為 |
genrule
查看規則來源genrule(name, srcs, outs, cmd, cmd_bash, cmd_bat, cmd_ps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, executable, features, licenses, local, message, output_licenses, output_to_bindir, restricted_to, tags, target_compatible_with, testonly, toolchains, tools, visibility)
genrule 會使用使用者定義的 Bash 指令產生一或多個檔案。
Genrules 是一般建構規則,如果任務沒有特定規則,您可以使用這些規則。舉例來說,您可以執行 Bash 一行指令。不過,如果您需要編譯 C++ 檔案,請遵循現有的 cc_* 規則,因為所有繁重的工作都已完成。
請注意,genrule 需要殼層來解讀指令引數。您也可以輕鬆參照 PATH 上提供的任意程式,但這會導致指令無法密封,且可能無法重現。如果您只需要執行單一工具,建議改用 run_binary。
就像其他動作一樣,genrules 建立的動作不應假設任何關於工作目錄的資訊;所有 Bazel 都保證,其宣告的輸入內容會在 $(location) 為其標籤傳回的路徑中提供。舉例來說,如果動作是在沙箱或遠端執行,沙箱或遠端執行的實作方式會決定工作目錄。如果直接執行 (使用 standalone 策略),工作目錄將是執行根目錄,也就是 bazel info execution_root 的結果。
請勿使用 genrule 執行測試。測試和測試結果有特殊豁免條款,包括快取政策和環境變數。一般來說,測試需要在建構完成後,且在目標架構上執行;而 genrules 則是在建構期間和執行架構上執行 (兩者可能不同)。如果您需要通用測試規則,請使用 sh_test。
跨平台編譯注意事項
如要進一步瞭解交叉編譯,請參閱使用手冊。
雖然 genrules 會在建構期間執行,但其輸出內容通常會在建構後用於部署或測試。請考慮為微控制器編譯 C 程式碼的範例:編譯器會接受 C 原始檔案,並產生在微控制器上執行的程式碼。產生的程式碼顯然無法在用於建構的 CPU 上執行,但 C 編譯器 (如果是從原始碼編譯) 本身必須執行。
建構系統會使用執行設定來說明建構作業執行的機器,並使用目標設定來說明建構作業輸出內容應執行的機器。它提供設定這些項目的選項,並將對應的檔案分隔至不同的目錄,以免發生衝突。
針對 genrules,建構系統會確保適當建構依附元件:視需要為target 設定建構 srcs,為exec 設定建構 tools,並將輸出內容視為target 設定。它還提供
「Make」變數,genrule 指令可將這些變數傳遞至對應工具。
genrule 刻意不定義 deps 屬性:其他內建規則會使用規則之間傳遞的語言相關元資料,自動判斷如何處理相關規則,但 genrule 無法達到這種程度的自動化。Genrules 僅在檔案和 runfiles 層級運作。
特殊情況
執行-執行編譯:在某些情況下,建構系統需要執行 genrules,以便在建構期間執行輸出內容。舉例來說,如果 genrule 建構某些自訂編譯器,而後者隨後會由另一個 genrule 使用,那麼第一個 genrule 就必須為執行設定產生輸出內容,因為編譯器會在另一個 genrule 中執行。在這種情況下,建構系統會自動執行正確的動作:為執行設定而非目標設定,建構第一個 genrule 的 srcs 和 outs。詳情請參閱使用手冊。
JDK 和 C++ 工具:如要使用 JDK 或 C++ 編譯器套件的工具,建構系統會提供一組可用的變數。詳情請參閱「"Make" 變數」一節。
Genrule 環境
使用 set -e -o pipefail 時,如果指令或管道失敗,則會執行 Bash 殼層,並在其中執行 genrule 指令。
建構工具會在經過淨化的程序環境中執行 Bash 指令,該環境只定義 PATH、PWD、TMPDIR 和其他幾個核心變數。為確保可重現建構作業,使用者 shell 環境中定義的大多數變數不會傳遞至 genrule 指令。不過,Bazel (而非 Blaze) 會傳遞使用者的 PATH 環境變數值。任何對 PATH 值所做的變更都會導致 Bazel 在下次建構時重新執行指令。
genrule 指令不應存取網路,除非是連結指令本身的子項程序,但這項規定目前並未強制執行。
建構系統會自動刪除任何現有的輸出檔案,但會在執行 genrule 之前建立所有必要的父系目錄。並在失敗時移除所有輸出檔案。
一般建議
- 請務必確保 genrule 執行的工具具備確定性和密封性。不應將時間戳記寫入輸出內容,且應使用穩定的集合和地圖排序,並且只將相對檔案路徑寫入輸出內容,而非絕對路徑。如果不遵循這項規則,就會導致非預期的建構行為 (Bazel 不會重建您認為會重建的 genrule),並降低快取效能。
- 請盡量使用
$(location)輸出內容、工具和來源。由於輸出檔案會依據不同的設定而分開,genrules 無法使用硬式編碼和/或絕對路徑。 - 如果在多個位置使用相同或非常相似的 genrule,請務必編寫通用的 Starlark 巨集。如果 genrule 很複雜,建議您在指令碼中或以 Starlark 規則的形式實作。這可改善可讀性和可測試性。
- 請務必確認退出碼正確指出 genrule 的成功或失敗情形。
- 請勿將資訊訊息寫入 stdout 或 stderr。雖然這對偵錯很有幫助,但很容易變成雜訊;成功的 genrule 應保持靜默。另一方面,失敗的 genrule 應發出良好的錯誤訊息。
$$evaluates to a$, a literal dollar-sign, so in order to invoke a shell command containing dollar-signs such asls $(dirname $x), one must escape it thus:ls $$(dirname $$x)。- 請避免建立符號連結和目錄。Bazel 不會複製 genrules 建立的目錄/符號連結結構,且其對目錄的依附元件檢查不健全。
- 在其他規則中參照 genrule 時,您可以使用 genrule 的標籤或個別輸出檔案的標籤。有時一種方法比較易讀,有時另一種方法比較易讀:在使用規則的
srcs中依名稱參照輸出內容,可避免不小心擷取 genrule 的其他輸出內容,但如果 genrule 產生許多輸出內容,這可能會很繁瑣。
範例
這個範例會產生 foo.h。因為指令不會接受任何輸入內容,因此沒有來源。指令執行的「二進位檔」是與 genrule 位於相同套件中的 Perl 指令碼。
genrule(
name = "foo",
srcs = [],
outs = ["foo.h"],
cmd = "./$(location create_foo.pl) > \"$@\"",
tools = ["create_foo.pl"],
)
以下範例說明如何使用 filegroup
和其他 genrule 的輸出內容。請注意,使用 $(SRCS) 取代明確的 $(location) 指示也能正常運作;這個範例為了示範起見,使用了後者。
genrule(
name = "concat_all_files",
srcs = [
"//some:files", # a filegroup with multiple files in it ==> $(locations)
"//other:gen", # a genrule with a single output ==> $(location)
],
outs = ["concatenated.txt"],
cmd = "cat $(locations //some:files) $(location //other:gen) > $@",
)
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 您可以在其他 BUILD 規則的 srcs 或 deps 部分,以名稱參照此規則。如果規則會產生來源檔案,您應使用 srcs 屬性。 |
srcs
|
標籤清單;預設為
這項屬性不適合用於列出由
建構系統會確保在執行 genrule 指令之前,先建構這些必要條件;這些必要條件會使用與原始建構要求相同的設定進行建構。這些必要條件的檔案名稱可透過 |
outs
|
由此規則產生的檔案清單。 輸出檔案不得跨越套件邊界。系統會將輸出檔案名稱解讀為相對於套件的相對路徑。
如果已設定
genrule 指令應會在預先指定的位置建立每個輸出檔案。您可以使用 genrule 專屬的「Make」變數 ( |
cmd
|
字串;預設為 $(location)
和 「Make」變數 的替換方式。
cmd_bash、cmd_ps 和 cmd_bat 均不適用,則會使用這個備用值。
如果指令列長度超過平台限制 (Linux/macOS 為 64K,Windows 為 8K),genrule 就會將指令寫入指令碼,並執行該指令碼來解決問題。這項規則適用於所有 cmd 屬性 ( |
cmd_bash
|
字串;預設為 此屬性的優先順序高於 |
cmd_bat
|
字串;預設為 此屬性的優先順序高於
|
cmd_ps
|
字串;預設為 這項屬性的優先順序高於
為了讓 Powershell 更容易使用且不易發生錯誤,我們會在 genrule 中執行 Powershell 指令前,先執行下列指令來設定環境。
|
executable
|
布林值;不可設定;預設值為
將此旗標設為 True 表示輸出內容是可執行檔案,可使用 系統不支援為產生的執行可供使用檔案宣告資料依附元件。 |
local
|
布林值;預設值為
如果設為 True,這個選項會強制
這相當於提供「local」做為標記 ( |
message
|
字串;預設為
執行這個建構步驟時會顯示的進度訊息。根據預設,訊息會顯示「產生輸出內容」(或其他同樣平淡的內容),但您可以提供更具體的訊息。請在 |
output_licenses
|
授權類型,預設為 common attributes
。
|
output_to_bindir
|
布林值;不可設定;預設值為
如果設為 True,這個選項會將輸出檔案寫入 |
toolchains
|
這個 genrule 允許存取的Make 變數目標集,或是這個 genrule 將存取的
透過 |
tools
|
標籤清單;預設為
建構系統會確保在執行 genrule 指令之前建構這些必要條件;由於這些工具會在建構作業中執行,因此會使用 exec 設定建構這些必要條件。您可以使用
任何 |
starlark_doc_extract
查看規則來源starlark_doc_extract(name, deps, src, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, render_main_repo_name, restricted_to, symbol_names, tags, target_compatible_with, testonly, visibility)
starlark_doc_extract() 會擷取規則、函式 (包括巨集)、面向和在特定 .bzl 或 .scl 檔案中定義或重新匯出的供應者相關文件。這個規則的輸出內容是 ModuleInfo 二進位值 Proto,如 Bazel 來源樹狀目錄中的 stardoc_output.proto 所定義。
隱含輸出目標
name.binaryproto(預設輸出內容):ModuleInfo二進位 protobuf。name.textproto(僅在明確要求時建構):name.binaryproto的文字版 Proto。
警告:這項規則的輸出格式不保證穩定。這項服務主要供 Stardoc 內部使用。
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
deps
|
標籤清單;預設為 src load() 包裝的 Starlark 檔案目標。在正常使用情況下,這些目標「應」是 bzl_library 目標,但 starlark_doc_extract 規則不會強制執行這項規定,而是接受任何在 DefaultInfo 中提供 Starlark 檔案的目標。請注意,包裝的 Starlark 檔案必須是來源樹狀結構中的檔案;Bazel 無法使用 |
src
|
標籤;必填 要用來擷取文件的 Starlark 檔案。請注意,這必須是來源樹狀結構中的檔案;Bazel 無法 |
render_main_repo_name
|
布林值;預設值為 //foo:bar.bzl 會以 @main_repo_name//foo:bar.bzl 的形式產生)。主要存放區使用的名稱可從主要存放區 如要為僅在同一個存放區內使用的 Starlark 檔案產生文件,請將這個屬性設為 |
symbol_names
|
字串清單;預設為
|
test_suite
查看規則來源test_suite(name, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, tests, visibility)
test_suite 定義一組對人類而言「有用」的測試。這可讓專案定義一組測試,例如「您必須在簽入前執行的測試」、「專案的壓力測試」或「所有小型測試」。bazel test 指令會遵循這種排序方式:對於 bazel test //some/test:suite 這類叫用,Bazel 會先列舉 //some/test:suite 目標間接包含的所有測試目標 (我們稱之為「test_suite expansion」),然後建構並測試這些目標。
範例
測試套件,用於執行目前套件中的所有小型測試。
test_suite(
name = "small_tests",
tags = ["small"],
)
執行特定一組測試的測試套件:
test_suite(
name = "smoke_tests",
tests = [
"system_unittest",
"public_api_unittest",
],
)
測試套件,可執行目前套件中所有穩定的測試。
test_suite(
name = "non_flaky_test",
tags = ["-flaky"],
)
引數
| 屬性 | |
|---|---|
name |
名稱;必填 這個目標的專屬名稱。 |
tags
|
字串清單;不可設定;預設為 開頭為「-」的標記視為排除標記。前面的「-」字元不屬於標記的一部分,因此「-small」套件標記與測試的「small」大小相符。所有其他標記都視為正面標記。 如要讓正面標記更明確,您可以選擇讓標記以「+」字元開頭,系統不會將該字元視為標記的一部分。只是讓正面和負面區別更容易閱讀。 只有符合所有正面標記的測試規則 (all) 和沒有任何負面標記的測試規則 (none) 才會納入測試套件。請注意,這並不表示會略過對篩除的測試依附元件的錯誤檢查;對略過的測試依附元件的依附元件仍需合法 (例如不會遭到可見度限制阻擋)。
請注意,測試的
如果您需要 |
tests
|
任何語言的測試套件和測試目標清單。
無論語言為何,都可以使用任何
如果未指定 |