函式

回報問題 查看來源

目錄

套件

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

這個函式會宣告適用於套件中所有規則的中繼資料。在套件 (BUILD 檔案) 中僅使用一次。

如果是宣告中繼資料套用至整個存放區中每個規則的對應項目,請在存放區根目錄使用 REPO.bazel 檔案中的 repo() 函式。repo() 函式使用的引數與 package() 完全相同。

應在檔案頂端的所有 load() 陳述式之後呼叫 package() 函式,並加上任何規則。

引數

屬性 說明
default_applicable_licenses

default_package_metadata 的別名。

default_visibility

標籤清單;預設值為 []

這個套件中規則的預設瀏覽權限。

除非規則的 visibility 屬性另有規定,否則這個套件中的每個規則都有這個屬性指定的瀏覽權限。如要進一步瞭解這項屬性的語法,請參閱瀏覽權限說明文件。套件預設瀏覽權限不適用於 exports_files (預設為公開檔案)。

default_deprecation

字串;預設值為 ""

設定這個套件中所有規則的預設 deprecation 訊息。

default_package_metadata

標籤清單;預設值為 []

設定預設清單,這些目標會套用至套件中的所有其他目標。這些目標通常與 OSS 套件和授權宣告相關。如需範例,請參閱 rules_license

default_testonly

布林值;預設為 False (除非註明中)

設定這個套件中所有規則的預設 testonly 屬性。

javatests 底下的套件,預設值為 True

features

清單字串;預設值為 []

設定各種會影響這個 BUILD 檔案語意的旗標。

這項功能主要由建構系統的人員使用,用於標記需要某些特殊處理的套件。除非建構系統的人員明確要求,否則請勿使用此屬性。

示例

以下宣告宣告,這個套件中的規則僅供套件群組 //foo:target 的成員查看。如果有規則的個別瀏覽權限宣告,則會覆寫此規格。
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

這個函式會定義一組套件,並將標籤與資料集建立關聯。您可以在 visibility 屬性中參照這個標籤。

套件群組主要用於控管瀏覽權限。公開可見的目標可從原始碼樹狀結構中的每個套件參照。私密可見目標只能在自有套件 (而非子套件) 中參照。在這類極端之間,目標可能會允許存取自身套件,以及一或多個套件群組描述的任何套件。如需瀏覽權限系統的詳細說明,請參閱瀏覽權限屬性。

如果指定套件與 packages 屬性相符,或已包含在 includes 屬性提及的其他套件群組中,系統就會將該套件視為群組。

套件群組在技術上來說是目標,但不是由規則建立,而且本身也沒有任何瀏覽權限保護。

引數

屬性 說明
name

名稱 (必填)

此目標的專屬名稱。

packages

字串清單;預設值為 []

零或多個套件規格的清單。

每個套件規格字串都可以採用下列其中一種格式:

  1. 套件的全名,不含存放區,從雙斜線開始。例如,//foo/bar 會指定具有該名稱的套件,且套件與套件群組位於相同的存放區。
  2. 如上所述,但結尾是 /...。例如, //foo/... 會指定 //foo 的一組和其所有子套件。//... 會指定目前存放區中的所有套件。
  3. publicprivate 字串,分別指定每個套件或沒有套件。(您必須設定旗標 --incompatible_package_group_has_public_syntax,才能使用這份表單)。

此外,前兩種套件規格也可以加上 - 的前置字串,表示已否定。

套件群組包含任何符合其至少一個正規格,且不符合其負面規格的任何套件。舉例來說,值 [//foo/..., -//foo/tests/...] 包含 //foo 的所有子套件,而不包含 //foo/tests 的子套件。(雖然包含 //foo 本身,而 //foo/tests 本身並沒有這項機制)。

除了公開瀏覽權限,您無法直接指定目前存放區以外的套件。

如果缺少這個屬性,就和將屬性設為空白清單一樣,等同於設為僅包含 private 的清單。

注意:在 Bazel 6.0 之前,規格 //... 的舊版行為與 public 相同。啟用 --incompatible_fix_package_group_reporoot_syntax 時,系統會修正這種行為,這是 Bazel 6.0 之後的預設狀態。

注意:在 Bazel 6.0 之前,如果這項屬性是 bazel query --output=proto (或 --output=xml) 的一部分進行序列化,則會省略開頭的斜線。舉例來說,//pkg/foo/... 會輸出 \"pkg/foo/...\"。啟用 --incompatible_package_group_includes_double_slash 時,此行為已修正,這是 Bazel 6.0 之後的預設狀態。

includes

標籤清單;預設值為 []

包含的其他套件群組。

這個屬性中的標籤必須參照其他套件群組。 系統會將參照套件群組中的套件視為這個套件群組的一部分。這是遞移性—如果套件群組 a 包含套件群組 b,而 b 包含套件群組 c,則 c 中的每個套件也會是 a 的成員。

與否定套件規格搭配使用時,請注意,系統會先獨立計算每個群組的套件組合,然後將結果聯集在一起。這表示在某個群組中排除的規格,不會影響其他群組中的規格。

示例

下列 package_group 宣告會指定名為「熱帶」的套件群組,其中包含熱帶水果。

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 旗標遭到翻轉為止。不過,這個行為不應仰賴並主動遷移。

引數

引數是目前套件中檔案名稱的清單。您也可以指定瀏覽權限宣告;在此情況下,指定的目標將可看到檔案。如未指定瀏覽權限,即使 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 模式,結果中會包含來源檔案的標籤。

includeexclude 清單包含與目前套件相關的路徑模式。每個模式可能包含一或多個路徑片段與 Unix 路徑一樣,這些片段會以 / 分隔。區隔可能包含 * 萬用字元:這會比對路徑區段中的任何子字串 (即使是空子字串),但排除目錄分隔符 /。此萬用字元可在一個路徑區段中多次使用。此外,** 萬用字元可以比對零或更完整的路徑區段,但必須宣告為獨立路徑區段。

示例:
  • foo/bar.txt 與這個套件中的 foo/bar.txt 檔案完全相符
  • 如果檔案結尾為 .txt,則 foo/*.txt 會比對 foo/ 目錄中的每個檔案 (除非 foo/ 是子套件)
  • foo/a*.htm* 會比對 foo/ 目錄中每個開頭為 a 的檔案,這個字串可以是任意字串 (可以是空白字串),然後有 .htm,並以另一個任意字串結尾,例如 foo/axx.htmfoo/a.htmlfoo/axxx.html
  • **/a.txt 會比對這個套件每個子目錄中的所有 a.txt 檔案
  • 如果產生的路徑至少有一個目錄呼叫 bar,則 **/bar/**/*.txt 會比對這個套件每個子目錄中的每個 .txt 檔案,例如 xxx/bar/yyy/zzz/a.txtbar/a.txt (請注意 ** 也與零區隔相符) 或 bar/zzz/a.txt
  • ** 會比對這個套件每個子目錄中的每個檔案
  • foo**/a.txt 是無效模式,因為 ** 必須獨立做為區隔

如果已啟用 exclude_directories 引數 (設為 1),則結果會省略類型目錄檔案 (預設值為 1)。

如果 allow_empty 引數設為 False,如果結果為空白清單,glob 函式就會發生錯誤。

以下是一些重要的限制和注意事項:

  1. 由於 glob() 在評估 BUILD 檔案時執行,因此 glob() 只會比對來源樹狀結構中的檔案,不會產生產生的檔案。如要建構的目標同時需要來源和產生的檔案,您必須將產生的檔案明確清單附加至 glob。請參閱下方包含 :mylib:gen_java_srcs範例

  2. 如果規則名稱與相符來源檔案相同,規則就會「覆蓋」檔案。

    為瞭解這一點,請記得 glob() 會傳迴路徑清單,因此在其他規則的屬性 (例如 srcs = glob(["*.cc"])) 中使用 glob() 的效果等同於明確列出相符的路徑。舉例來說,如果 glob() 產生 ["Foo.java", "bar/Baz.java"],但套件中也有名為「Foo.java」的規則 (雖然 Bazel 警告這一點,但仍允許),則 glob() 的使用者將使用「Foo.java」規則 (其輸出內容) 而非「Foo.java」檔案。詳情請參閱 GitHub 問題 #10395

  3. Globs 可能會比對子目錄中的檔案。子目錄名稱可以使用萬用字元。不過...
  4. 標籤不得跨越套件邊界,而 glob 與子套件中的檔案不相符。

    例如,如果 x/y 是做為套件 (可能是 x/y/BUILD 或套件路徑上的其他位置),套件 x 中的 glob 運算式 **/*.cc 就不會包含 x/y/z.cc。這表示 glob 運算式的結果實際上取決於 BUILD 檔案的存在。也就是說,如果沒有名為 x/y 的套件,或者未使用 --deleted_packages 標記將其標示為已刪除,相同的 glob 運算式會包含 x/y/z.cc

  5. 上述限制適用於所有 glob 運算式,無論使用的萬用字元為何。
  6. 檔案名稱開頭為 . 的隱藏檔案會透過 *** 萬用字元完全比對。如要比對含有複合模式的隱藏檔案,您的模式必須以 . 開頭。舉例來說,*.*.txt 會比對 .foo.txt,但 *.txt 不會。隱藏目錄也會以同樣的方式比對。隱藏的目錄可能包含不需要做為輸入內容的檔案,而且可能會增加不必要的混亂檔案數量和記憶體用量。如要排除隱藏目錄,請將目錄新增至「排除」清單引數。
  7. 「**」萬用字元具有一個角大小寫字元:模式 "**" 與套件的目錄路徑不相符。換句話說,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",
    ],
    ...
)

在目錄測試資料中加入所有 txt 檔案 ( experiment.txt 除外)。 請注意,不含測試資料子目錄中的檔案。如要納入這些檔案,請使用遞迴 glob (**)。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

遞迴 Glob 範例

進行測試時,需將測試資料目錄及其所有子目錄中的所有文字檔案 (以及子目錄等) 納入考量。 系統會忽略含有 BUILD 檔案的子目錄。(請參閱上方的限制和注意事項)。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

根據這個目錄和所有子目錄建構程式庫,除了路徑包含測試目錄的檔案以外,建立程式庫。請盡量避免採用此模式,因為這可減少建構增量,進而增加建構時間。

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 標記。舉例來說,您可以使用這項功能,定義平台專屬的依附元件,或根據規則是以「開發人員」和「發布」模式來嵌入不同的資源。

基本使用方法如下:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

如此一來,sh_binary 的一般標籤清單指派作業就會替換為將設定條件對應至相符值的 select 呼叫,藉此設定 sh_binarysrcs 屬性。每個條件都是 config_settingconstraint_value 的標籤參照,如果目標的設定與預期值組合相符,「相符」。mytarget#srcs 的值會成為與目前叫用相符的標籤清單。

注意:

  • 在任何叫用中僅選取一個條件。
  • 如果同時符合多個條件,而其中一個條件是其他條件的特殊,系統會優先採用專業化。如果 B 擁有與 A 相同的所有標記和限制值,再加上一些其他的標記或限制值,則條件 B 會視為條件 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() 會列出子套件,而非檔案和目錄。這個檔案使用的路徑模式與 glob() 相同,且能比對目前載入 BUILD 檔案直接子系的任何子套件。如需包含和排除模式的詳細說明和範例,請參閱 glob

    傳回的子套件清單會按照排序順序排列,且包含與目前載入套件 (符合 include 中的指定模式) 相符的路徑,而非 exclude 中的路徑。

    範例

    以下範例列出 foo/BUILD 套件的所有直接子套件

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    一般而言,我們建議使用者使用 skylib 的「subpackages」模組,而非直接呼叫這個函式。