規則
別名
查看規則來源alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
alias
規則會建立可供參照的規則名稱。
別名只適用於「一般」目標。具體來說,package_group
和 test_suite
無法使用別名。
在大型存放區中,如果要變更目標,就必須變更許多檔案,這時使用別名可能會有所幫助。如果您想針對多個目標重複使用該邏輯,也可以使用別名規則來儲存 select 函式呼叫。
別名規則有其專屬的顯示宣告。在所有其他方面,它的行為會與它參照的規則相同 (例如,系統會忽略「在別名上」上的測試;會改用所參照規則的測試用途),但有某些次要例外:
-
如果指令列中提到別名,系統就不會執行測試。如要定義執行參照測試的別名,請使用
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
|
字典:字串 -> 字串;nonconfigurable;預設值為 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
|
字典:label -> 字串;nonconfigurable;預設值為 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
,而非直接參照目錄。後者並不失真,因為建構系統無法充分瞭解目錄下的所有檔案,因此在這些檔案變更時,可能不會進行重建。與 glob 搭配使用時,filegroup
可以確保建構系統明確知道所有檔案。
範例
如要建立包含兩個來源檔案的 filegroup
,請執行以下操作:
filegroup( name = "mygroup", srcs = [ "a_file.txt", "some/subdirectory/another_file.txt", ], )
或者,使用 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()
會執行以 Blaze 查詢語言指定的查詢,並將結果傾印至檔案。
為了維持建構作業的一致性,查詢只能造訪 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。
請勿使用 genrule 執行測試。測試和測試結果有特殊豁免條款,包括快取政策和環境變數。一般來說,測試需要在建構完成後,且在目標架構上執行;而 genrules 則是在建構期間和執行架構上執行 (兩者可能不同)。如果您需要通用測試規則,請使用 sh_test
。
跨平台程式碼編譯注意事項
如要進一步瞭解交叉編譯,請參閱使用手冊。
雖然 genrules 會在建構期間執行,但其輸出內容通常會在建構後用於部署或測試。請考慮為微控制器編譯 C 程式碼的範例:編譯器會接受 C 原始檔案,並產生在微控制器上執行的程式碼。產生的程式碼顯然無法在用於建構的 CPU 上執行,但 C 編譯器 (如果是從原始碼編譯) 本身必須執行。
建構系統會使用 exec 設定來描述執行建構作業的機器,以及目標設定,藉此說明應在哪個機器上執行建構作業的輸出內容。它提供設定這些項目的選項,並將對應的檔案分隔至不同的目錄,以免發生衝突。
針對 Genrules,建構系統會確保正確建構依附元件:系統會視需要為 target 設定建構 srcs
、針對 exec 設定建構 tools
,並將輸出內容視為用於 target 設定。它也提供 「Make」變數,讓 genrule 指令可將其傳遞至對應工具。
genrule 刻意並未定義 deps
屬性:其他內建規則會使用規則之間傳遞的語言相關中繼資訊,自動判斷如何處理相依規則,但 genrules 無法採用這種自動化程度。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 無法使用硬式編碼和/或絕對路徑。 - 編寫通用的 Starlark 巨集,以便在多個位置使用相同或非常類似的 Genrules。如果 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,這個選項會強制
相當於以標記 ( |
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
的文字 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
用於定義一組測試,這些測試對使用者來說「實用」。這可讓專案定義一組測試,例如「您必須在簽入前執行的測試」、「專案的壓力測試」或「所有小型測試」。blaze test
指令會遵循這種組織方式:對於 blaze test //some/test:suite
這類叫用,Blaze 會先列舉 //some/test:suite
目標間接包含的所有測試目標 (我們稱之為「test_suite expansion」),然後 Blaze 會建構並測試這些目標。
範例
測試套件,用於執行目前套件中的所有小型測試。
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
|
各種語言的測試套件和測試目標。
無論語言為何,都可以使用任何
如果未指定 |