規則
別名
查看規則來源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)
與預期的設定狀態相符 (以建構標記或平台限制表示),以便觸發可設定的屬性。如要瞭解如何使用此規則,請參閱「select」一文,如要瞭解一般功能的總覽,請參閱「 可設定屬性」。
範例
以下會比對任何設定 --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,建構系統會確保適當建構依附元件:srcs
會根據需要為target 設定建構,tools
會根據exec 設定建構,而輸出內容則視為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,這個選項會將輸出檔案寫入 |
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
的文字版 Protobuf。
警告:這項規則的輸出格式不保證穩定。這項服務主要供 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
|
任何語言的測試套件和測試目標清單。
無論語言為何,都可以使用任何
如果未指定 |