存放區規則

回報問題 查看原始碼 夜間 7.4 ,直接在 Google Cloud 控制台實際操作。 7.3 7.2 7.1 7.0 6.5

本頁面說明如何建立存放區規則,並提供 瞭解詳情

外部存放區是指僅可在 WORKSPACE 檔案中使用的規則,可在 Bazel 的載入階段啟用非密封作業。每項外部存放區規則都會建立自己的工作區, 具備 BUILD 檔案和構件若是依賴第三方 程式庫 (例如 Maven 封裝程式庫),但也會產生 BUILD 檔案 專屬於執行 Bazel 的主機

建立存放區規則

.bzl 檔案中,使用 repository_rule 函式來建立新的篩選條件 並儲存在全域變數中

自訂存放區規則的使用方式與原生存放區規則相同。這項服務 具有必要的 name 屬性,且其建構檔案中每個目標皆有 即 @<name>//package:target,其中 <name>name 屬性。

規則會在您明確建立或 建構過程在這種情況下,Bazel 會執行 implementation 函式。這個函式說明如何建立存放區、其內容和 BUILD 檔案。

屬性

屬性是做為字典,傳遞至 attrs 規則引數的規則引數。 定義存放區規則時,系統會列出定義的屬性和類型。以下範例將 urlsha256 屬性定義為字串:

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.namerepo_mapping 的含義與原生存放區規則 local_repositorynew_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 構件產生建構目標。