規則
別名
alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
alias
規則會建立另一個規則可參照的名稱。
別名只適用於「一般」目標。具體來說,package_group
和 test_suite
無法使用別名。
別名規則有其專屬的顯示宣告。在其他方面,它會像參照的規則一樣運作 (例如,系統會忽略別名上的 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
,而非直接參照目錄。後者是不安全的,因為建構系統無法完全瞭解目錄下方的所有檔案,因此可能不會在這些檔案變更時重新建構。搭配使用 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, 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/..."]
)。
系統會使用 --order_output=full
排序 genquery 的輸出內容,以便強制產生確定性的輸出內容。
輸出檔案的名稱即為規則名稱。
範例
這個範例會將指定目標的傳遞閉包中標籤清單寫入檔案。
genquery( name = "kiwi-deps", expression = "deps(//kiwi:kiwi_lib)", scope = ["//kiwi:kiwi_lib"], )
引數
屬性 | |
---|---|
name |
這個目標的專屬名稱。 |
expression
|
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, exec_tools, 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 執行測試。測試和測試結果有特殊豁免條款,包括快取政策和環境變數。一般來說,測試需要在建構完成後,且在目標架構上執行;而 genrules 則是在建構期間,且在主機架構上執行 (兩者可能不同)。如果您需要一般用途的測試規則,請使用 sh_test
。
跨平台編譯注意事項
如要進一步瞭解交叉編譯,請參閱使用手冊。
雖然 genrules 會在建構期間執行,但其輸出內容通常會在建構後用於部署或測試。請考慮為微控制器編譯 C 程式碼的範例:編譯器會接受 C 原始檔案,並產生在微控制器上執行的程式碼。產生的程式碼顯然無法在用於建構的 CPU 上執行,但 C 編譯器 (如果是從原始碼編譯) 本身必須執行。
建構系統會使用主機設定來描述建構作業執行的機器,並使用目標設定來描述建構作業輸出內容應執行的機器。它提供設定這些項目的選項,並將對應的檔案分隔至不同的目錄,以免發生衝突。
針對 genrules,建構系統會確保適當建構依附元件:srcs
會 (視需要) 為目標設定建構,tools
會為主機設定建構,且輸出內容會視為目標設定。它還提供
「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 指令前,先執行下列指令來設定環境。
|
exec_tools
|
tools 屬性完全相同,但這些依附元件會針對規則的執行平台而非主機設定進行設定。這表示 exec_tools 中的依附元件不受 tools 中依附元件的限制。特別是,不需要為自己的傳遞依附元件使用主機設定。詳情請參閱 tools 。
Blaze 團隊正在將所有 |
executable
|
將此旗標設為 True 表示輸出內容是可執行檔案,可使用 系統不支援為產生的執行可供使用檔案宣告資料依附元件。 |
local
|
如果設為 True,這個選項會強制
這相當於提供「local」做為標記 ( |
message
|
執行這個建構步驟時會顯示的進度訊息。根據預設,訊息會顯示「產生輸出內容」(或其他同樣平淡的訊息),但您可以提供更具體的訊息。請在 |
output_licenses
|
common attributes
。 |
output_to_bindir
|
如果設為 True,這個選項會將輸出檔案寫入 |
tools
|
建構系統會確保在執行 genrule 指令之前建構這些必要條件。由於這些工具會在建構作業中執行,因此會使用 主機設定建構這些必要條件。您可以使用
任何 |
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
|
無論語言為何,這裡都接受任何
如果未指定 |