本頁說明如何建立存放區規則,並提供範例以瞭解詳情。
外部存放區是一種只能在 WORKSPACE
檔案中使用的規則,可在 Bazel 載入階段啟用非密封作業。每個外部存放區規則都會建立自己的工作區,以及自己的 BUILD
檔案和構件。這些程式庫可用於依附第三方程式庫 (例如 Maven 封裝程式庫),也可以產生執行時所在的主機 Bazel 專屬的 BUILD
檔案。
建立存放區規則
在 .bzl
檔案中,使用 repository_rule 函式建立新的存放區規則,並將其儲存在全域變數中。
自訂存放區規則的使用方式和原生存放區規則相同。它具有必要的 name
屬性,其建構檔案中的每個目標皆可稱為 @<name>//package:target
,其中 <name>
是 name
屬性的值。
當您明確建構規則,或規則為建構的依附元件時,系統就會載入規則。在這種情況下,Bazel 會執行其 implementation
函式。此函式說明如何建立存放區,以及存放區的內容和 BUILD
檔案。
屬性
屬性是規則引數,例如 url
或 sha256
。定義存放區規則時,您必須列出屬性及其類型。
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_repository
和 new_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 構件產生建構目標。