規則
別名
alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
alias
規則會建立另一個規則名稱。
別名僅適用於「一般」目標。具體來說,package_group
和 test_suite
不能是別名。
別名規則有專屬的瀏覽權限宣告。在其他方面,此行為與參照的規則類似 (例如,系統會忽略「在別名上僅供測試」;系統會改用所參照規則的僅供測試性),但有一些次要例外狀況:
-
如果指令列中提及其別名,系統就不會執行測試。如要定義執行參照測試的別名,請在
tests
屬性中使用具有單一目標的test_suite
規則。 -
定義環境群組時,系統不支援
environment
規則的別名。當然,--target_environment
指令列選項也不支援這些 API。
範例
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" }, )
以下為假設有包含 //example:glibc_2_25
標籤的 constraint_value
且指定使用 x86_64 架構和 glibc 2.25 版的平台版本。請注意,如果平台定義超過這兩個值的其他限制值,則平台仍符合比對條件。
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 旗標),當"a"
出現在實際清單中的「任何位置」時,values = { "flag": "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
|
config_setting 必須指定的下限 constraint_values 組合。(這裡不考慮執行平台)。系統會忽略平台有的其他限制值。詳情請參閱「
可設定的建構屬性」一文。
如果 |
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(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( 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 執行測試。測試和測試結果有特殊的分配比例,包括快取政策和環境變數。測試通常需要在建構作業完成後以及在目標架構上執行,而 GenRule 會在建構期間和主機架構上執行 (兩者可能不同)。如需一般用途測試規則,請使用 sh_test
。
跨編譯注意事項
請參閱使用手冊,進一步瞭解跨平台編譯。
雖然 Genrules 在建構期間執行,但其輸出內容通常會在建構後使用,用於部署或測試。請參考編譯微控制器的 C 程式碼編譯範例:編譯器接受 C 來源檔案,然後產生在微控制器上執行的程式碼。產生的程式碼顯然無法在用於建構的 CPU 上執行,但 C 編譯器 (如果是從原始碼編譯) 本身需要執行。
建構系統會使用主機設定描述要執行建構作業的機器,以及目標設定來描述應執行建構作業輸出內容的機器。這套系統提供設定各選項的選項,可將對應檔案分隔成不同目錄,以免衝突。
針對 genrules,建構系統會確保正確建構依附元件:系統會視需要為 目標 設定建構 srcs
、針對 host 設定建構 tools
,並將輸出內容視為適用於 目標 設定。同時也提供
「Make」變數,讓 Genrule 指令能夠傳送至對應的工具。
Genrule 是刻意定義任何 deps
屬性:其他內建規則會使用在規則之間傳遞的語言相關中繼資訊,自動決定如何處理相依規則,但 Genrule 無法實現這種自動化程度。Genrules 只適用於檔案和執行檔案層級,
特殊情況
主機主機編譯:在某些情況下,建構系統需要執行 Genrules,才能在建構期間執行輸出。舉例來說,如果 Genrule 會建構一些自訂編譯器,且後續由其他 Genrule 使用,則第一項必須為主機設定產生輸出內容,因為該編譯器會在另一個 Genrule 中執行。在此情況下,建構系統會自動執行正確的作業:建構主機設定的第一個 Genrule 的 srcs
和 outs
,而非目標設定。詳情請參閱使用手冊。
JDK 與 C++ 工具:如要使用 JDK 或 C++ 編譯器套件中的工具,建構系統會提供一組要使用的變數。詳情請參閱「Make」變數一節。
Genrule 環境
genrule 指令是由 Bash 殼層執行,此為使用 set -e -o pipefail
,設為在指令或管道失敗時失敗。
建構工具會在經過淨化的程序環境中執行 Bash 指令,該環境僅定義核心變數,例如 PATH
、PWD
、TMPDIR
等。為確保建構可重現,使用者殼層環境中定義的大部分變數都不會透過 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 指令預計會在預先定義的位置建立每個輸出檔案。在 |
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」(或同等的「Bland」),但您可以提供較具體的訊息。在 |
output_licenses
|
common attributes
|
output_to_bindir
|
如果設為 True,這個選項會使輸出檔案寫入 |
tools
|
建構系統會確保在執行 genrule 指令前建立這些先決條件;這些工具是使用 host 設定建構,因為這些工具會在建構作業中執行。您可以使用
任何要由 |
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 擴充」),然後 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」套件標記符合測試的「小」大小。所有其他標記都會視為正標記。 或者,如要提高正向標記的明確性,您也可以選擇以「+」字元做為開頭,系統不會將這類標記當做標記文字的一部分進行評估。只讓正面和負面的差異更容易閱讀。 只有符合「所有」正標記和「無」排除標記的測試規則才會納入測試套件。請注意,這並不代表系統會略過針對已篩除測試的依附元件檢查錯誤,但已略過測試的依附元件仍需合法 (例如不會因瀏覽權限限製而封鎖)。
請注意,系統會將測試的
如果需要 |
tests
|
無論使用的語言為何,在此接受
如果 |