標籤

所有目標只能屬於一個套件。目標的名稱稱為其「標籤」。每個標籤都代表一個目標。標準形式的一般標籤如下所示:

@myrepo//my/app/main:app_binary

標籤的第一個部分是存放區名稱 @myrepo//。在一般情況下,標籤參照的存放區與來源存放區相同,存放區 ID 可以使用縮寫為 //。因此,在 @myrepo 中,這個標籤通常寫成

//my/app/main:app_binary

標籤的第二個部分是不符資格的套件名稱 my/app/main,這是套件相對於存放區根目錄的路徑。存放區名稱和不合格的套件名稱形成了完整的套件名稱 @myrepo//my/app/main。如果標籤參照了套件名稱,則可省略套件名稱 (及選用冒號)。因此,在 @myrepo//my/app/main 中,這個標籤可透過下列任一方式編寫:

app_binary
:app_binary

我們的慣例上,系統會忽略檔案中的冒號,但對規則仍會保留,但並不重要。

標籤中冒號後的部分,app_binary 是不符資格的目標名稱。如果該元件與套件路徑的最後一個元件相符,則可能會省略該元件和冒號。因此,以下兩個標籤的效果相同:

//my/app/lib
//my/app/lib:lib

套件子目錄中檔案目標的名稱,是檔案相對於套件根目錄 (包含 BUILD 檔案的目錄) 的路徑。因此,這個檔案位於存放區的 my/app/main/testdata 子目錄中:

//my/app/main:testdata/input.txt

//my/app@some_repo//my/app 等字串會根據其使用的背景資訊有兩個意義:當 Bazel 預期的標籤時,它們分別代表 //my/app:app@some_repo//my/app:app。不過,當 Bazel 預期收到套件 (例如 package_group 規格) 時,會參照包含該標籤的套件。

BUILD 檔案中的常見錯誤是使用 //my/app 參照套件,或是參照套件中的「所有」目標,而不是。請注意,這等同於 //my/app:app,因此會在目前存放區的 my/app 套件中,為 app 目標命名。

不過,建議您在 package_group.bzl 檔案中使用 //my/app 參照套件,因為該套件會明確說明套件名稱是絕對且根層級目錄的絕對目錄。

相對標籤無法用來參照其他套件中的目標;在這種情況下,您必須一律指定存放區 ID 和套件名稱。舉例來說,如果來源樹狀結構包含 my/app 套件和 my/app/testdata 套件 (這兩個目錄都有自己的 BUILD 檔案),則後者套件會包含名為 testdepot.zip 的檔案。有兩種方式 (一個錯誤、一個正確) 在 //my/app:BUILD 中參照這個檔案:

錯誤 - testdata 是不同的套件,因此無法使用相對路徑

testdata/testdepot.zip

正確 — 使用完整路徑參照 testdata

//my/app/testdata:testdepot.zip

@// 開頭的標籤是主要存放區的參照,即使來自外部存放區,仍可正常運作。因此,如果從外部存放區參照,則 @//a/b/c//a/b/c 不同。前者會返回主要存放區,後者會在外部存放區中尋找 //a/b/c。在參照主要存放區目標的主要存放區中編寫規則時,這一點尤其重要,也會從外部存放區使用。

如要瞭解各種參照目標的方式,請參閱目標模式相關說明。

標籤的詞法規格

標籤語法不建議使用具有殼層特殊意義的中繼字元,這有助於避免不小心引用問題,也能更輕鬆地建構操控標籤的工具和指令碼,例如 Bazel 查詢語言

以下提供指定目標名稱的具體詳細資料。

目標名稱:package-name:target-name

target-name 是套件中的目標名稱。規則的名稱是 BUILD 檔案中規則宣告的 name 屬性值;檔案名稱則是相對於包含 BUILD 檔案目錄的路徑名稱。

目標名稱必須完全由擷取自 azAZ09 組合的字元,以及標點符號符號 !%-@^_"#$&'()*-+,;<=>?[]{|}~/. 組成。

檔案名稱必須是一般格式的相對路徑名稱,也就是不得以正斜線做為開頭或結尾 (例如禁止使用 /foofoo/),也不得含有多個連續斜線做為路徑分隔符 (例如 foo//bar)。同樣地,系統禁止使用上層級參照 (..) 和目前的目錄參照 (./)。

錯誤:請勿使用「..」參照其他套件中的檔案

正確 — 使用 `//package-name:filename`

雖然在檔案目標的名稱中使用 / 是很常見的情況,但請避免在規則名稱中使用 /。特別是使用標籤的簡短形式時,可能會混淆讀者。即使沒有這類套件 foo/bar/wiz//foo/bar/wiz 標籤一律是 //foo/bar/wiz:wiz 的簡寫,即使該目標存在,也一律不會參照 //foo:bar/wiz

但在某些情況下,使用斜線或甚至有必要。舉例來說,特定規則的名稱必須與主體來源檔案相符,且該來源檔案可能位於套件的子目錄中。

套件名稱 - //package-name:target-name

套件名稱是包含其 BUILD 檔案的目錄名稱 (相對於所屬存放區的頂層目錄)。例如:my/app

套件名稱必須完全由從 A-Zaz09、「/」、「-」、「.」、「@」和「_」組合中的字元組成,且開頭不得為斜線。

如果語言的目錄結構對其模組系統 (例如 Java) 具有重大影響,請務必選擇該語言中有效 ID 的目錄名稱。

雖然 Bazel 支援工作區根套件中的目標 (例如 //:foo),但最好將套件留空,讓所有有意義的套件都具有描述性名稱。

套件名稱不得包含子字串 //,也不得以斜線結尾。

規則

規則會指定輸入和輸出之間的關係,以及建構輸出的步驟。規則可以是多種不同種類 (有時稱為「規則類別」),這會產生已編譯的執行檔和程式庫、測試執行檔,以及其他支援的輸出內容,如「建構 Enlopedia」所述。

BUILD 檔案會叫用規則來宣告目標

在以下範例中,我們會看到使用 cc_binary 規則的目標 my_app 宣告。

cc_binary(
    name = "my_app",
    srcs = ["my_app.cc"],
    deps = [
        "//absl/base",
        "//absl/strings",
    ],
)

每個規則叫用都有 name 屬性 (必須是有效的目標名稱),可在 BUILD 檔案的套件中宣告目標。

每個規則都有一組「屬性」;特定規則的適用屬性,以及每個屬性的重要性和語意都是該規則的函式。如需規則清單及其對應屬性,請參閱建構百科全書。每個屬性都有名稱和類型。屬性可具有的常見類型包括整數、標籤、標籤清單、字串、字串清單、輸出標籤、輸出標籤清單。並非所有規則都需要指定所有屬性。因此屬性會形成字典,從鍵 (名稱) 到選用的輸入值。

許多規則中的 srcs 屬性具有「標籤清單」類型;其值 (如果有的話) 都是標籤清單,每個標籤都是這個規則的輸入目標名稱。

在某些情況下,規則種類的名稱是任意的,更有趣的是規則產生的檔案名稱,這對於 Genrules 來說就很有意思。詳情請參閱一般規則:genrule

在其他情況下,名稱也非常重要:以 *_binary*_test 規則為例,規則名稱會決定建構作業產生的執行檔名稱。

這與目標相關的有向非循環圖稱為「目標圖表」或「建構依附元件圖表」,也是 Bazel 查詢工具運作的網域。

目標 建立檔案