Bazel 模組是可包含多個版本的 Bazel 專案,而且每個 ,該物件會發布依附的其他模組相關中繼資料。這是 類似其他依附元件管理系統中熟悉的概念 Maven 構件、npm 套件、Go 模組或 Cargo crate。
模組的存放區根目錄必須包含 MODULE.bazel
檔案 (位於
WORKSPACE
檔案)。這個檔案是模組的資訊清單,宣告其名稱
版本、直接依附元件清單以及其他資訊基本概念
範例:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
查看 MODULE.bazel
檔案中可用指令的完整清單。
為了執行模組解析,Bazel 會先讀取根模組的
MODULE.bazel
檔案,然後重複要求任何依附元件的
MODULE.bazel
檔案從 Bazel 登錄檔移除,直到該檔案為止
即可查看完整的依附元件圖表
根據預設,Bazel 接著會選取每個模組的一個版本 。Bazel 會用存放區代表每個模組,並諮詢該註冊資料庫 ,瞭解如何定義各個存放區。
版本格式
Bazel 的生態系統五花八門,而專案會使用不同的版本管理架構。
目前為止最受歡迎的是 SemVer
也經常使用不同配置來知名的專案
Abseil,
版本都是以日期表示,例如 20210324.2
)。
因此,Bzlmod 採用較寬鬆的 SemVer 規格版本。 差異包括:
- SemVer 闡述了「release」部分版本必須包含 3 個
區隔:
MAJOR.MINOR.PATCH
。在 Bazel 中,這項要求會放寬,因此 ,任意數量的區隔都可使用。 - 在 SemVer 中,「release」中的每個區段部分只能由數字組成。 在 Bazel 中,這會導致字母和比較 語意符合「ID」「預先發布版」部分。
- 另外,還有大、小和修補程式版本的語意 沒有強制執行的指令不過,請參閱相容性等級,瞭解 並詳細說明我們如何表示回溯相容性
任何有效的 SemVer 版本都是有效的 Bazel 模組版本。此外,兩個
SemVer 版本 a
和 b
會比較 a < b
的情況,包括是否在
並與 Bazel 模組版本做比較
選擇版本
請考慮鑽石依附元件問題,也就是版本化依附元件中的基石 管理空間假設您有一個依附關係圖:
A 1.0
/ \
B 1.0 C 1.1
| |
D 1.0 D 1.1
應使用哪個版本的「D
」?為解決這個問題,Bzlmod 使用
選擇最小版本
Go 模組系統導入的 (MVS) 演算法。MVS 會假設
模組的版本具有回溯相容性,因此請挑選最高版本
任何相依物件 (本例中的 D 1.1
)。將其稱為「最小化」
因為 D 1.1
是符合我們要求的最早版本。
即使有 D 1.2
以上版本,也不會選取使用 MVS 會建立
高保真可重現的版本選擇程序。
彎曲版本
如果有特定版本應避免使用,註冊資料庫可將特定版本宣告為「yanked」
(例如安全漏洞)。Bazel 在選取
模組的 Shaked 版本。如要修正這個錯誤,請升級至新版
避免變形語,或是使用
--allow_yanked_versions
敬上
旗標,明確允許該版本。
相容性等級
在 Go 中,MVS 根據回溯相容性的假設能夠正常運作,因為它會將
回溯不相容的模組版本做為個別模組。目標
SemVer,這表示 A 1.x
和 A 2.x
被視為不同的模組,且
與已解析的依附元件圖中存在。換句話說
在 Go 套件路徑中編碼主要版本,因此沒有任何
編譯時間或連結時間衝突
然而,Bazel 無法提供這類保證,因此需要「主要版本」
數字,以便偵測回溯不相容的版本。這組號碼稱為
相容性等級,由其中的每個模組版本指定
module()
指令。有了這項資訊,Bazel 便可在發生錯誤時擲回錯誤
偵測是否有不同相容性等級的同一模組
都存在於已解析的依附元件圖中
覆寫
在 MODULE.bazel
檔案中指定覆寫值,以修改 Bazel 的行為
模組的解析度。只有根模組的覆寫值會生效 (如果模組
做為依附元件,系統會忽略其覆寫值
每個覆寫值都是由特定模組名稱指定,影響了該模組的所有 依附元件圖表中列出各個版本雖然只有根模組的覆寫 可能適用於根模組並未 並直接依附於
單一版本覆寫
- 使用
version
屬性,即可將依附元件固定在特定 版本,不受 Deployment 中要求的依附元件版本 依附關係圖 - 透過
registry
屬性,您可以強制這個依附元件來自 而非一般的註冊資料庫 選取流程 - 在
patch*
屬性中,您可以指定一組要套用的修補程式 下載的模組
這些屬性為選用屬性,可以混合搭配。
多重版本覆寫
multiple_version_override
您可以指定多個版本,讓同一模組的多個版本共存
已解析的依附關係圖
您可以指定明確的模組可用版本清單, 全都列在依附元件圖中,才能解決 (必須存在) 一些遞移依附元件,視每個允許的版本而定。更新後 ,但 Bazel 升級時,系統只會保留允許的模組版本 其他版本的模組 (例如相同的 Pod 版本) 至最接近的可用版本 相容性等級。沒有其他具備相同相容性的版本 Bazel 會擲回錯誤
舉例來說,如果 1.1
、1.3
、1.5
、1.7
和 2.0
版本存在於
問題在於依附元件圖,而非主要版本。
等級:
- 如果覆寫
1.3
、1.7
和2.0
的多重版本覆寫值,1.1
即將升級至1.3
,1.5
將升級至1.7
, 不同的版本 - 如果覆寫
1.5
和2.0
的多重版本覆寫方法會導致錯誤,1.7
沒有具備相同相容性等級的版本,無法升級至該版本。 - 如果覆寫
1.9
和2.0
的多重版本覆寫方法會導致錯誤,1.9
未出現在解析前的依附元件圖表中。
此外,使用者也可以使用 registry
覆寫登錄檔。
屬性,與單一版本覆寫機制類似。
非登錄檔覆寫
非登錄檔覆寫會將模組從版本解析中完全移除。Bazel
未向註冊資料庫要求這 MODULE.bazel
檔案,而是向
存放區本身
Bazel 支援下列非登錄檔覆寫:
定義不代表 Bazel 模組的存放區
透過 bazel_dep
,您可以定義代表其他 Bazel 模組的存放區。
有時候,您需要定義「不」代表 Bazel 的存放區
module;例如,內含要當做資料讀取的純 JSON 檔案。
在這種情況下,您可以使用 use_repo_rule
指令,直接定義存放區
叫用存放區規則這個存放區只會顯示在其模組中
實際上,實作時會使用與 module 相同的機制實作 擴充功能,可讓您定義包含更多 靈活彈性
存放區名稱和嚴格依附元件
備份 Deployment 的存放區 apparent name
模組直接依附於其模組名稱,除非
bazel_dep
的 repo_name
屬性
指令。請注意,這表示模組只能找出
依附元件這有助於防止因
遞移依附元件
備份 Deployment 的標準名稱
模組為 module_name~version
(例如 bazel_skylib~1.0.3
) 或 module_name~
(例如 bazel_features~
),視是否有
整個依附元件圖表中,模組有多種版本 (請參閱
multiple_version_override
)。
請注意,標準名稱格式不是您應依附於
隨時可能變動。相較於硬式編碼為正規名稱
請使用支援的方法,直接從 Bazel 取得該檔案:
* 如果是 BUILD 和 .bzl
檔案中,請使用
Label
執行個體上的 Label.repo_name
透過存放區的明顯名稱提供的標籤字串所建構,例如
Label("@bazel_skylib").repo_name
。
* 查詢執行檔案時,請使用
$(rlocationpath ...)
敬上
或 Google Cloud 控制台的
@bazel_tools//tools/{bash,cpp,java}/runfiles
,或者針對規則集 rules_foo
,
在 @rules_foo//foo/runfiles
中。
* 透過外部工具 (例如 IDE 或語言) 與 Bazel 互動時
伺服器,請使用 bazel mod dump_repo_mapping
指令從
指定一組存放區的標準名稱。
模組擴充功能也可以引入其他存放區 將深入探討模組的可見範圍