目錄
包裹
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
這個函式可以宣告適用於 套件。在套件 (BUILD 檔案) 中僅使用一次。
宣告中繼資料要套用至整體規則中各項規則的對應工具
存放區,請使用 repo()
函式的
REPO.bazel
檔案。
repo()
函式使用的引數與 package()
完全相同。
畫面頂端所有 load() 陳述式的後面都應呼叫 package() 函式 檔案。
引數
屬性 | 說明 |
---|---|
default_applicable_licenses |
|
default_visibility |
標籤清單;預設為 這個套件中規則的預設瀏覽權限。 這個套件中的每個規則都有指定的瀏覽權限
屬性,除非 |
default_deprecation |
String;預設值為 設定預設值
|
default_package_metadata |
標籤清單;預設為 設定要套用至套件中所有其他目標的預設中繼資料目標清單。 這些目標通常與 OSS 套件和授權宣告相關。 如需範例,請參閱 rules_license。 |
default_testonly |
布林值;預設為 設定預設值
|
features |
清單字串;預設值為 設定各種會影響這個 BUILD 檔案語意的旗標。 這項功能主要由建構系統的工作人員使用 需要特殊處理的代碼套件除非 明確要求。 |
範例
以下宣告會宣告這個套件中的規則 只有套件的成員可以看見 群組「//foo:target
」。個人瀏覽權限聲明
如果有一項規則,請覆寫這個規格。
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
這個函式會定義一組套件
並將標籤與資料集建立關聯標籤可在以下位置中參照:
visibility
屬性。
套件群組主要用於控管瀏覽權限。公開顯示 目標架構可以從來源樹狀結構中的每個套件參照。私密 可見目標只能在本身的套件 (而非子套件) 中參照。 在這些極端之間,目標或許會允許存取自身套件加上任何 一或多個套件群組描述的套件內容。如要進一步瞭解 可見權限系統的說明,請參閱 瀏覽權限 屬性。
如果指定套件符合
packages
屬性,或已包含在另一個項目中
includes
屬性中提及的套件群組。
套件群組在技術上屬於目標,但不是由規則建立,而且 就沒有任何瀏覽權限保護
引數
屬性 | 說明 |
---|---|
name |
名稱;必選 此目標的專屬名稱。 |
packages |
字串清單;預設值為 零或多個套件規格的清單。 每個套件規格字串都可以包含下列其中一個值: 表單:
此外,前兩種套件規格
前方加上 套件群組包含至少符合下列其中一項條件的套件:
正面規格,與任何負面規格皆不相符
例如 除了公開顯示的瀏覽權限之外,你也無法直接指定 目前存放區以外的套件 如果缺少這個屬性,就等於將屬性設為
空白清單,作用就和將清單設為包含
僅 注意:在 Bazel 6.0 之前,規格為 注意:在 Bazel 6.0 之前,此屬性被序列化為
|
includes |
標籤清單;預設為 包含的其他套件群組。 這個屬性中的標籤必須參照其他套件群組。
參照套件群組中的套件將納入此元件
套件群組。如果這是遞移性 (如果套件群組)
與否定套件規格搭配使用時,請注意, 系統會先單獨計算每個群組的套件組合 然後,系統會將結果聯集在一起也就是說 不會影響 另一個群組。 |
範例
下列 package_group
宣告會指定
名為「tropical」的套件群組含有熱帶水果。
package_group( name = "tropical", packages = [ "//fruits/mango", "//fruits/orange", "//fruits/papaya/...", ], )
下列宣告內容指定虛構的套裝方案群組 應用程式:
package_group( name = "fooapp", includes = [ ":controller", ":model", ":view", ], ) package_group( name = "model", packages = ["//fooapp/database"], ) package_group( name = "view", packages = [ "//fooapp/swingui", "//fooapp/webui", ], ) package_group( name = "controller", packages = ["//fooapp/algorithm"], )
exports_files
exports_files([label, ...], visibility, licenses)
exports_files()
會指定屬於
並匯出至其他套件
套件的 BUILD 檔案只能直接參照
加入其他套件
exports_files()
陳述式。進一步瞭解
檔案的瀏覽權限。
做為舊版行為,凡是被提及為規則輸入內容的檔案,系統都會匯出
保持啟用狀態,直到標記
--incompatible_no_implicit_file_export
敬上
但快速又簡單然而,出現這種情況時,不應仰賴並主動採取這個做法
其他用途
引數
引數是目前套件中檔案名稱的清單。A 罩杯
也可以指定瀏覽權限宣告在這個範例中
所有指定目標都能查看如果未指定瀏覽權限,
會向每個套件顯示
指定於 package
函式。授權
也可以指定
範例
以下範例會匯出 golden.txt
,
來自 test_data
套件的文字檔案,因此其他
例如,在 data
屬性中,套件可能會使用
測試
# from //test_data/BUILD exports_files(["golden.txt"])
Glob
glob(include, exclude=[], exclude_directories=1, allow_empty=True)
Glob 是一種輔助函式 可尋找符合特定路徑模式的檔案 並傳回新的可變動且已排序的清單。Glob 只會搜尋檔案 本身俱備專屬套件,而且只會尋找來源檔案 (不會產生 其他目標)。
如果來源檔案的套件相對路徑,結果會包含在結果中
路徑符合任一 include
模式,但沒有任何
exclude
個模式。
include
和 exclude
清單包含路徑模式
則是與目前套件相對的每個模式都可能包含一個或
和 Unix 路徑一樣,這些區隔會按照
/
。模式中區隔會與
路徑區隔可能包含 *
萬用字元:比對
路徑區隔中的任何子字串 (即使是空子字串),但不包括
目錄分隔符 /
這個萬用字元可以多次使用
可將單一路徑納入同一個路徑此外,**
萬用字元可以比對
零或多個完整路徑區隔,但必須宣告為獨立路徑
路徑片段
foo/bar.txt
與foo/bar.txt
檔案完全相符 (除非foo/
是子套件)foo/*.txt
與foo/
目錄中的每個檔案相符 如果檔案結尾為.txt
(除非foo/
為 子檔案包)foo/a*.htm*
與foo/
中的所有檔案相符 目錄開頭為a
,然後含有任意字串 (可以 也就是空白),然後具有.htm
,並以另一個任意字串結尾 (除非foo/
為子套件);例如foo/axx.htm
和foo/a.html
或foo/axxx.html
foo/*
與foo/
目錄中的所有檔案相符, (除非foo/
為子套件);與foo
不符 將exclude_directories
設為 0 分foo/**
會比對每個非子套件子目錄中的所有檔案 位於套件的第一個子目錄foo/
下如果exclude_directories
已設為 0,foo
目錄本身也符合模式;在本例中,**
是 視為與零路徑區隔相符**/a.txt
與這個套件的a.txt
個檔案相符 目錄以及非子套件子目錄**/bar/**/*.txt
比對每個.txt
檔案 非子目錄的子目錄 (如果 產生的路徑稱為bar
,例如xxx/bar/yyy/zzz/a.txt
或bar/a.txt
(請注意, 「**
」也與零區隔相符) 或「bar/zzz/a.txt
」**
會比對出以下每個非子套件子目錄中的所有檔案 這個套件foo**/a.txt
為無效的模式,因為**
必須 獨立於foo/
是無效的模式,因為第二個定義的區段/
之後是空字串
如果 exclude_directories
引數已啟用 (設為 1),
type 目錄會省略結果中 (預設值為 1)。
如果 allow_empty
引數設為 False
,
glob
函式會在結果可能是
空白清單。
以下是幾個重要的限制和注意事項:
-
glob()
會在評估 BUILD 檔案期間執行,glob()
只會比對來源樹狀結構中的檔案,永遠不會比對 產生的檔案。如果您建立的目標需要 來源和產生的檔案,您必須附加 將檔案複製到 glob請參閱範例 下方列出:mylib
和:gen_java_srcs
。 -
如果規則名稱與相符的來源檔案相同,規則就會 「陰影」檔案。
為了瞭解這一點,請注意
glob()
會傳回 路徑,因此請在其他規則中使用glob()
屬性 (例如srcs = glob(["*.cc"])
) 的效果與列出 進行比對舉例來說,如果glob()
產生 「["Foo.java", "bar/Baz.java"]
」,但規則中還設有規則 名為「Foo.java」的套件(雖然 Bazel 發出了警告,但還是可以這麼做) 接著,glob()
的使用者將使用「Foo.java」規則 (其輸出內容) 而非「Foo.java」檔案。詳情請見 GitHub 問題 #10395 瞭解詳情。 - Globs 可能會比對子目錄中的檔案。以及子目錄名稱 可能遭到萬用字元編碼。不過...
-
標籤不得跨越套件邊界,而 glob 可以 和子套件中的檔案不相符。
例如:套件中的 glob 運算式
**/*.cc
如果符合以下條件,x
不包含x/y/z.cc
x/y
是以套件形式存在 (可以是x/y/BUILD
,或套件路徑上的其他位置)。這個 表示 glob 運算式的結果實際上取決於 BUILD 檔案的存在,也就是說,相同的 glob 運算式 如果沒有呼叫套件,請包含x/y/z.cc
x/y
,或是使用 --deleted_packages 旗標。 - 上述限制適用於所有 glob 運算式、 無論使用何種萬用字元。
-
以「
.
」開頭的隱藏檔案完全符合以下條件:**
和*
萬用字元。是否要比對隱藏的檔案 模型的開頭必須是.
。例如:*
和.*.txt
將與.foo.txt
相符,但*.txt
則無效。 隱藏目錄也會以同樣的方式比對。隱藏的目錄 可能包含不必做為輸入內容的檔案, 不必要的大量毀損檔案數量及記憶體用量。排除目標 請將它們加進 [排除]list 引數。 -
「**」萬用字元有一個邊角大小寫:模式
"**"
與套件的目錄路徑不符。也就是 說,「glob(["**"], exclude_directories = 0)
」與所有檔案相符 檔案和目錄,完全放在目前套件的 目錄下 (當然,我們不會去子套件的目錄,請參閱先前 注意事項
一般來說,建議您嘗試提供適當的擴充功能 (例如 *.html) 而不是使用 bare '*' 來進行 glob 模式。更明確的名稱 都需自行記錄,確保不會意外比對到備份 檔案,或是 emacs/vi/... 自動儲存檔案。
編寫建構規則時,您可以列舉 glob 的元素。這個 能為每個輸入內容產生個別規則詳情請參閱 展開的 glob 範例一節。
Glob 範例
根據這個目錄中的所有 Java 檔案,建立 Java 程式庫。
以及 :gen_java_srcs
規則產生的所有檔案
java_library( name = "mylib", srcs = glob(["*.java"]) + [":gen_java_srcs"], deps = "...", ) genrule( name = "gen_java_srcs", outs = [ "Foo.java", "Bar.java", ], ... )
在目錄 testdata 中加入所有 txt 檔案 ( experiment.txt 除外)。 請注意,不含測試資料子目錄中的檔案。如果 您希望納入這些檔案,請使用遞迴 glob (**)。
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob( ["testdata/*.txt"], exclude = ["testdata/experimental.txt"], ), )
遞迴 Glob 範例
讓測試依附於 testdata 目錄中的所有 txt 檔案, 其子目錄 (及其子目錄等)。 系統會忽略含有 BUILD 檔案的子目錄。(查看限制 和上述注意事項)
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob(["testdata/**/*.txt"]), )
根據這個目錄中的所有 Java 檔案,建立程式庫 子目錄。 請盡量避免採用這個模式,因為這可能會減少建構 進而增加建構時間。
java_library( name = "mylib", srcs = glob( ["**/*.java"], exclude = ["**/testing/**"], ), )
展開的 Glob 範例
在目前的目錄中為 *_test.cc 建立個別的 Genrule ,計算檔案中的行數。
# Conveniently, the build language supports list comprehensions. [genrule( name = "count_lines_" + f[:-3], # strip ".cc" srcs = [f], outs = ["%s-linecount.txt" % f[:-3]], cmd = "wc -l $< >$@", ) for f in glob(["*_test.cc"])]
如果上方的 BUILD 檔案位於 //foo 套件中,且套件含有三個
相符的檔案、a_test.cc、b_test.cc 和 c_test.cc,然後執行
bazel query '//foo:all'
會列出所有產生的規則:
$ bazel query '//foo:all' | sort //foo:count_lines_a_test //foo:count_lines_b_test //foo:count_lines_c_test
選取
select( {conditionA: valuesA, conditionB: valuesB, ...}, no_match_error = "custom message" )
select()
是建立規則屬性的輔助函式
可設定。
它可以取代
幾乎
任何屬性指派,因此其值取決於指令列 Bazel 標記。
舉例來說,您可以使用這項功能定義平台專屬的依附元件,或
根據「developer」
與「發行」相較模式。
基本使用方法如下:
sh_binary( name = "mytarget", srcs = select({ ":conditionA": ["mytarget_a.sh"], ":conditionB": ["mytarget_b.sh"], "//conditions:default": ["mytarget_default.sh"] }) )
這會讓 srcs
屬性
取代一般標籤即可設定的 sh_binary
清單指派,並加上對應 select
的呼叫
比對值每個條件都是一個標籤
參照
是config_setting
或
constraint_value
,
「符合」如果目標設定與預期的一組
輕鬆分配獎金mytarget#srcs
的值會成為
標籤清單與目前的叫用相符
注意:
- 每次叫用都僅選取一個條件。
- 如果多個條件相符,其中一個是其他條件的特殊認證 以專業認證來說系統會將條件 B 視為 如果 B 具有相同的標記和限制,則條件 A 的專業 值加上 A,再加上一些其他旗標或限制值。這也 代表在建立訂單時, 如下方範例 2 所示
- 如果符合多個條件,其中一個不是所有條件的專業化 其餘條件,除非所有條件解析為相同的值,否則 Bazel 將因發生錯誤而失敗。
- 特殊虛擬標籤
//conditions:default
為 如果沒有符合其他條件,則會視為相符。如果這項條件成立 其他規則必須符合這些條件才不會發生錯誤。 select
可嵌入內部較大的 屬性。因此,srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})
和srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})
都是有效的運算式。select
適用於大多數屬性,但並非全部屬性。不相容 在相關說明文件中標示nonconfigurable
。子套件
subpackages(include, exclude=[], allow_empty=True)
subpackages()
是類似glob()
的輔助函式 會列出子套件,而非檔案和目錄。這個 API 也使用相同的 視為glob()
的路徑模式,且能比對 目前載入的 BUILD 檔案的直接子系。如需包含和篩選資料的詳細說明及範例,請參閱 glob 排除模式。傳回的子套件清單會按照排序順序,包含 目前載入套件中符合指定模式的路徑
include
而非exclude
中的使用者。範例
以下範例會列出
foo/BUILD
套件的所有直接子套件# The following BUILD files exist: # foo/BUILD # foo/bar/baz/BUILD # foo/bar/but/bad/BUILD # foo/sub/BUILD # foo/sub/deeper/BUILD # # In foo/BUILD a call to subs1 = subpackages(include = ["**"]) # results in subs1 == ["sub", "bar/baz", "bar/but/bad"] # # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of # 'foo' subs2 = subpackages(include = ["bar/*"]) # results in subs2 = ["bar/baz"] # # Since 'bar' is not a subpackage itself, this looks for any subpackages under # all first level subdirectories of 'bar'. subs3 = subpackages(include = ["bar/**"]) # results in subs3 = ["bar/baz", "bar/but/bad"] # # Since bar is not a subpackage itself, this looks for any subpackages which are # (1) under all subdirectories of 'bar' which can be at any level, (2) not a # subpackage of another subpackages. subs4 = subpackages(include = ["sub"]) subs5 = subpackages(include = ["sub/*"]) subs6 = subpackages(include = ["sub/**"]) # results in subs4 and subs6 being ["sub"] # results in subs5 = []. # # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a # subpackage of 'foo'). # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since # 'foo/sub' is already a subpackage itself, the subdirectories will not be # traversed anymore. # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it # is returned. But the subdirectories of 'foo/sub' will not be traversed # anymore.
一般而言,最好不要直接呼叫這個函式 使用者將「子套件」的模組 skylib。