Bazel 支援外部依附元件,也就是文字和二進位檔的來源檔案 有哪些建構項目例如 GitHub 存放區、Maven 構件或本機目錄代管的規則集 執行虛擬機器
從 Bazel 6.0 開始,您可以透過 Bazel 管理外部依附元件:
著重於存放區的傳統 WORKSPACE
系統,以及
新型的 MODULE.bazel
系統 (代號為 Bzlmod),
並利用標記 --enable_bzlmod
啟用)。這兩個系統
但 Bzlmod 會在日後的 Bazel 中取代 WORKSPACE
系統
請參閱 Bzlmod 遷移指南,瞭解如何
遷移。
本文說明外部依附元件管理的相關概念 在 Bazel 中,再依序介紹這兩個系統。
概念
存放區
目錄樹狀結構,其根目錄有界線標記檔案,內含來源 可在 Bazel 建構作業中使用的檔案通常會縮短為只有 repo。
存放區邊界標記檔案可以是 MODULE.bazel
(表示這個存放區位於)
代表 Bazel 模組、REPO.bazel
(請參閱下文),或
舊版結構定義,WORKSPACE
或 WORKSPACE.bazel
。任何存放區邊界標記檔案
會顯示存放區的邊界多個這類檔案
目錄。
主要存放區
正在執行目前 Bazel 指令的存放區。
工作區
所有 Bazel 指令共用的環境都會在同一個主要存放區中執行。
請注意,以往「存放區」的概念和「工作區」已經 混淆;「workspace」一詞經常用來指稱 有時甚至會用作「存放區」的同義詞
標準存放區名稱
存放區可定址的正規名稱,在
工作區,每個存放區都有一個正式名稱。存放區中的目標
標籤的標準名稱為 canonical_name
@@canonical_name//pac/kage:target
(請注意雙精度 @
)。
主要存放區一律以空字串做為標準名稱。
顯示的存放區名稱
存放區名稱可透過其他特定存放區來定址。
這可以視為存放區的「nickname」:含有標準名稱的存放區
michael
在存放區中可能有名為 mike
的顯示名稱
alice
,但存放區中的顯示名稱可能有 mickey
,
bob
。在此情況下,標籤可以處理 michael
內的目標
以 alice
為基準的 @mike//pac/kage:target
(注意單一 @
)。
相反地,每個存放區也可以視為「存放區對應」。 維護「apparent 存放區名稱」的對應關係「標準存放區名稱」
存放區規則
存放區定義的結構定義,用於指示 Bazel 如何具體化
Cloud Storage 也提供目錄同步處理功能舉例來說,您可以「從特定網址下載 ZIP 封存檔
將內容擷取出來」,或「擷取特定 Maven 構件,並提供給
java_import
目標」或直接「符號連結本機目錄」。每個存放區
定義:使用適當數量引數呼叫存放區規則。
如要進一步瞭解如何寫入,請參閱「存放區規則」 自己的存放區規則
目前為止,最常見的存放區規則是
http_archive
,用於下載封存檔案
從網址擷取並擷取
local_repository
,這會對
已有 Bazel 存放區的本機目錄
擷取存放區
透過執行相關聯的存放區,允許本機磁碟使用存放區 儲存空間規則無法在本機磁碟上使用工作區中定義的存放區 才能擷取。
一般來說,Bazel 只會在需要存放區中的內容時擷取存放區 而存放區可能尚未擷取如果系統已擷取存放區 但是 Bazel 只會在定義有所變更時重新擷取。
fetch
指令可用來啟動存放區的預先擷取作業。
或執行任何建構的必要存放區這項功能
使用 --nofetch
選項啟用離線版本。
--fetch
選項可用於管理網路存取權。其預設值為 true。
不過,設為 false (--nofetch
) 時,指令會使用任何快取的
依附元件版本,如果沒有的話,指令就會產生
失敗。
詳情請參閱「擷取選項」 控制擷取作業的相關資訊
目錄版面配置
擷取完畢後,該存放區就位於以下子目錄的 external
「輸出基準」。
您可以執行下列指令,查看含有
正規名稱 canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
REPO.bazel 檔案
REPO.bazel
檔案是用於標記目錄樹狀結構的最頂層界線
可構成存放區的容器您不必包含任何內容就能當做存放區
邊界檔案;不過,這項功能也能用來指定
存放區中的所有建構目標
REPO.bazel
檔案的語法與 BUILD
檔案類似,差別在於沒有
系統支援 load
陳述式,且只有單一函式 repo()
支援
廣告。repo()
使用與 package()
相同的引數
函式中的 BUILD
檔案;而 package()
指定套件中所有建構目標的通用屬性 repo()
存放區中所有建構目標的做法類似。
舉例來說,您可以透過下列方式為存放區中的所有目標指定通用授權:
包含下列 REPO.bazel
檔案:
repo(
default_package_metadata = ["//:my_license"],
)
使用 Bzlmod 管理外部依附元件
新的外部依附元件子系統 Bzlmod 無法直接與存放區搭配使用 定義。而會從模組建構依附元件圖表,並 extensions,並據此定義存放區。
Bazel 模組是可以有多個 Bazel 專案
每個版本都會發布其他依附的模組相關中繼資料
保持開啟。模組的存放區根目錄必須有一個 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")
模組只能列出直接依附元件,Bzlmod 會在
Bazel 登錄檔 — 預設為 Bazel Central
註冊資料庫。登錄檔 提供
依附元件MODULE.bazel
檔案,可讓 Bazel 探索
執行版本解析作業前的遞移依附元件圖
版本解析後,請為每個模組選取一個版本。
Bazel 會再次查詢登錄檔,藉此瞭解如何為每個模組定義存放區
(在大多數情況下,使用 http_archive
)。
模組也可以指定稱為標記的自訂資料片段, 模組解析後耗用的模組擴充功能。 定義其他存放區這些擴充功能的功能與存放區類似 讓他們能執行檔案 I/O 和傳送網路等動作 要求。除了其他要素,Bazel 也能用來與其他套件互動 同時遵循透過 Bazel 建立的依附元件圖表 模組。
Bzlmod 上的外部連結
- bazelbuild/examples 中的 Bzlmod 使用範例
- Bazel 外部依附元件超額更新 (原始的 Bzlmod 設計文件)
- BazelCon 2021 在 Bzlmod 上談論
- Bzlmod 上的 Bazel Community Day
使用 WORKSPACE
定義存放區
以往,您可以在
WORKSPACE
(或 WORKSPACE.bazel
) 檔案。這個檔案的語法與
BUILD
檔案,採用存放區規則,而非建構規則。
以下程式碼片段示範如何在以下程式碼中使用 http_archive
存放區規則:
WORKSPACE
檔案:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)
這個程式碼片段會定義標準名稱為 foo
的存放區。在「WORKSPACE
」中
根據預設,存放區的正規名稱也是
其他所有存放區中
如需可用函式的完整清單,請參閱這篇文章:
WORKSPACE
個檔案。
WORKSPACE
系統的缺點
WORKSPACE
系統採用後,使用者回報
許多難題,包括:
- Bazel 不會評估任何依附元件的
WORKSPACE
檔案,因此 必須在主要項目的WORKSPACE
檔案中定義轉換依附元件 存放區和存放區 - 為解決這個問題,專案採用「deps.bzl」模式,
他們會定義一個巨集,而這個巨集會定義多個存放區,並要求使用者
在
WORKSPACE
檔案中呼叫這個巨集。- 這有其本身的問題:巨集無法
load
其他.bzl
檔案,因此 這些專案必須定義其遞移依附元件 「deps」巨集的特殊功能,或是由使用者多次呼叫 多層「deps」巨集。 - Bazel 會依序評估
WORKSPACE
檔案。此外, 是以包含網址的http_archive
指定依附元件,不含任何網址 版本資訊。換句話說,在執行任務時 鑽石依附元件的版本解析版本 (A
取決於B
和C
;B
和C
都依附於不同版本的D
)。
- 這有其本身的問題:巨集無法
由於 WORKSPACE 方面的缺點,Bzlmod 會把舊版資料 WORKSPACE 系統,用於日後的 Bazel 版本。請參閱 Bzlmod 遷移 指南。