本頁面說明如何建立存放區規則,並提供 瞭解詳情
外部存放區是指僅可在 WORKSPACE
檔案中使用的規則,可在 Bazel 的載入階段啟用非密封作業。每項外部存放區規則都會建立自己的工作區,
具備 BUILD
檔案和構件若是依賴第三方
程式庫 (例如 Maven 封裝程式庫),但也會產生 BUILD
檔案
專屬於執行 Bazel 的主機
建立存放區規則
在 .bzl
檔案中,使用
repository_rule 函式來建立新的篩選條件
並儲存在全域變數中
自訂存放區規則的使用方式與原生存放區規則相同。這項服務
具有必要的 name
屬性,且其建構檔案中每個目標皆有
即 @<name>//package:target
,其中 <name>
是
name
屬性。
規則會在您明確建立或
建構過程在這種情況下,Bazel 會執行 implementation
函式。這個函式說明如何建立存放區、其內容和 BUILD
檔案。
屬性
屬性是做為字典,傳遞至 attrs
規則引數的規則引數。
定義存放區規則時,系統會列出定義的屬性和類型。以下範例將 url
和 sha256
屬性定義為字串:
local_repository = repository_rule(
implementation=_impl,
local=True,
attrs={
"url": attr.string(mandatory=True)
"sha256": attr.string(mandatory=True)
}
)
如要在實作函式中存取屬性,請使用 repository_ctx.attr.<attribute_name>
:
def _impl(repository_ctx):
url = repository_ctx.attr.url
checksum = repository_ctx.attr.sha256
所有 repository_rule
都有隱含定義的屬性 (就像建構一樣)
規則)。兩個隱含屬性為 name
(如同建構規則)
repo_mapping
。存放區規則名稱可透過以下資源存取:
repository_ctx.name
。repo_mapping
的含義與原生存放區規則 local_repository
和 new_local_repository
相同。
如果屬性名稱開頭為 _
,表示屬性為私有,使用者無法設定。
實作函式
每個存放區規則都需要 implementation
函式。這個 SDK 包含
規則的實際邏輯,並嚴格在「載入階段」中執行。
這個函式只有一個輸入參數 repository_ctx
。這個函式會傳回 None
,表示在指定參數下可重現規則,或是傳回含有該規則一組參數的字典,可將該規則轉換為可重現的規則,產生相同的存放區。舉例來說,如果規則追蹤的是 Git 存放區,則會傳回特定提交 ID,而不是原本指定的浮動分支。
輸入參數 repository_ctx
可用於
存取屬性值,以及非密封函式 (尋找二進位檔、
執行二進位檔、在存放區建立檔案或下載檔案
來自網際網路)。如需更多背景資訊,請參閱程式庫。範例:
def _impl(repository_ctx):
repository_ctx.symlink(repository_ctx.attr.path, "")
local_repository = repository_rule(
implementation=_impl,
...)
實作函式何時執行?
當 Bazel 需要該存放區的目標時,就會執行存放區的實作函式,例如當另一個目標 (在另一個存放區中) 依附於該存放區,或是在指令列中提及該存放區時。實作函式應會在檔案系統中建立存放區。這就是所謂的「擷取」存放區
與一般目標相比,在下列情況中,存放區不一定會重新擷取 會造成存放區不同的變更這是因為 Bazel 無法偵測變更,或是會導致每次建構作業產生過多額外負擔 (例如從網路擷取的內容)。因此,只有在下列項目發生變更時,系統才會重新擷取存放區:
- 在
WORKSPACE
檔案中傳遞至存放區宣告的參數。 - Starlark 程式碼,內含存放區的實作。
- 傳遞至
repository_ctx
的任何環境變數值getenv()
方法,或使用environ
屬性宣告的repository_rule
。您可以使用--repo_env
旗標,在指令列上硬連線這些環境變數的值。 - 傳遞至
read()
、execute()
和類似內容的任何檔案內容 由標籤參照的repository_ctx
方法 (例如//mypkg:label.txt
,但不含mypkg/label.txt
) - 執行
bazel sync
時。
repository_rule
有兩個參數可控制重新擷取存放區的時間:
- 如果設定了
configure
標記,則只會在bazel sync
,如果--configure
參數傳遞至該參數 (如果 屬性,這項指令不會重新擷取) 如果設定了
local
旗標,除了上述情況外,存放區也會 當 Bazel 伺服器重新啟動,或有任何會影響 存放區變更的宣告 (例如WORKSPACE
檔案或檔案) 載入容器時,不論這些變更是否造成 宣告內容在這種情況下,系統不會重新擷取非本機存放區。這是因為這些存放區會與網路通訊,或會造成高額費用。
重新啟動實作函式
如果所要求的依附元件缺少,則在擷取存放區時,實作函式可以重新啟動。在這種情況下,實作函式的執行作業會停止,缺少的依附元件會解析,並在解析依附元件後重新執行函式。為避免不必要的重啟作業 (這項作業成本高昂,因為可能需要重複存取網路),系統會預先擷取標籤引數,前提是所有標籤引數都能解析為現有檔案。請注意,解決 只在執行期間建構的字串或標籤路徑 可能仍然會造成重新啟動
強制重新擷取外部存放區
外部存放區有時有可能過時,且無須變更
定義或依附元件舉例來說,存放區擷取來源可能
會追蹤第三方存放區的特定分支版本,而新的修訂版本
可在該分支版本上使用在這種情況下,您可以呼叫 bazel sync
,要求 Bazel 無條件重新擷取所有外部存放區。
此外,有些規則會檢查本機電腦,且可能會使
但本機機器在升級時
資料仍舊存在你可以請 bazel 來
系統只會重新擷取
repository_rule
定義了 configure
屬性,請使用 bazel sync --configure
。
範例
C++ 自動設定工具鍊: 系統就會使用存放區規則 Bazel 的 C++ 設定檔,方法是尋找本機 C++ 編譯器, 環境和 C++ 編譯器支援的標記。
Go 存放區 使用多個
repository_rule
定義依附元件清單 才能使用 Go 規則rules_jvm_external 預設會建立名為
@maven
的外部存放區,為傳遞依附元件樹狀結構中的每個 Maven 構件產生建構目標。