存放區規則

回報問題 查看原始碼 Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

本頁面將說明如何建立存放區規則,並提供範例供您參考。

外部存放區是指僅可在 WORKSPACE 檔案中使用的規則,可在 Bazel 的載入階段啟用非密封作業。每個外部存放區規則都會建立專屬的工作區,並包含專屬的 BUILD 檔案和構件。這些檔案可用於依附第三方程式庫 (例如 Maven 封裝的程式庫),但也可以用於產生特定於 Bazel 主機執行作業的 BUILD 檔案。

建立存放區規則

.bzl 檔案中,使用 repository_rule 函式建立新的存放區規則,並將其儲存在全域變數中。

自訂存放區規則的使用方式與原生存放區規則相同。它具有必要的 name 屬性,且其建構檔案中的每個目標都可以稱為 @<name>//package:target,其中 <name>name 屬性的值。

您明確建構規則,或規則是建構作業的依附元件時,系統就會載入規則。在這種情況下,Bazel 會執行 implementation 函式。這個函式說明如何建立存放區、其內容和 BUILD 檔案。

屬性

屬性是規則引數,例如 urlsha256。定義存放區規則時,您必須列出屬性及其類型。

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={"path": attr.string(mandatory=True)})

如要存取屬性,請使用 repository_ctx.attr.<attribute_name>

所有 repository_rule 都會隱含定義屬性 (就像建構規則一樣)。這兩個隱含屬性分別是 name (與建構規則相同) 和 repo_mapping。您可以使用 repository_ctx.name 存取存放區規則的名稱。repo_mapping 的含義與原生存放區規則 local_repositorynew_local_repository 相同。

如果屬性名稱開頭為 _,表示屬性為私有,使用者無法設定。

實作函式

每個存放區規則都需要 implementation 函式。它包含規則的實際邏輯,且會嚴格地在載入階段執行。

這個函式只有一個輸入參數 repository_ctx。這個函式會傳回 None,表示在指定參數下可重現規則,或是傳回含有該規則一組參數的字典,可將該規則轉換為可重現的規則,產生相同的存放區。舉例來說,如果規則用於追蹤 git 存放區,則會傳回特定提交 ID,而非原先指定的浮動分支版本。

輸入參數 repository_ctx 可用於存取屬性值和非密封函式 (尋找二進位檔、執行二進位檔、在存放區中建立檔案或從網路下載檔案)。如需更多背景資訊,請參閱程式庫。範例:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

實作函式何時執行?

如果儲存庫宣告為 local,則依附元件圖表中的依附元件 (包括 WORKSPACE 檔案本身) 變更會導致執行實作函式。

如果實作函式要求的依附元件缺少,則可重新啟動該函式。依附元件解析後,實作函式的開頭會重新執行。為避免不必要的重啟作業 (這項作業成本高昂,因為可能需要重複進行網路存取),系統會預先擷取標籤引數,前提是所有標籤引數都能解析為現有檔案。請注意,從字串或僅在執行函式時建構的標籤解析路徑,可能仍會導致重新啟動。

最後,對於非 local 存放區,只有下列依附元件的變更可能導致重新啟動:

  • 定義存放區規則所需的 .bzl 檔案。
  • WORKSPACE 檔案中宣告存放區規則。
  • 使用 repository_rule 函式的 environ 屬性宣告的任何環境變數值。您可以使用 --action_env 標記,透過指令列強制設定這些環境變數的值 (但這個標記會使建構的每個動作失效)。
  • 標籤所使用的任何檔案內容 (例如 //mypkg:label.txt,而非 mypkg/label.txt)。

強制重新擷取外部存放區

有時,外部存放區可能會在定義或依附元件未變更的情況下過時。舉例來說,存放區擷取來源可能會追蹤第三方存放區的特定分支,而該分支會提供新的修訂版本。在這種情況下,您可以呼叫 bazel sync,要求 Bazel 無條件重新擷取所有外部存放區。

此外,部分規則會檢查本機電腦,如果本機電腦已升級,這些規則可能會過時。您可以在這裡要求 Bazel 只重新擷取 repository_rule 定義設有 configure 屬性集的那些外部存放區,請使用 bazel sync --configure

範例

  • C++ 自動設定工具鍊:使用存放區規則,透過查看本機 C++ 編譯器、環境和 C++ 編譯器支援的標記,自動為 Bazel 建立 C++ 設定檔。

  • Go 存放區會使用多個 repository_rule 定義使用 Go 規則所需的依附元件清單。

  • rules_jvm_external 預設會建立名為 @maven 的外部存放區,為傳遞依附元件樹狀結構中的每個 Maven 構件產生建構目標。