外部依附元件總覽

回報問題 查看來源 夜間 7.2 7.1 7.0 6.5 6.4

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 (請參閱下文),或 舊版結構定義,WORKSPACEWORKSPACE.bazel。任何存放區邊界標記檔案 會顯示存放區的邊界多個這類檔案 目錄。

主要存放區

正在執行目前 Bazel 指令的存放區。

主要存放區的根目錄也稱為 workspace root

工作區

所有 Bazel 指令共用的環境都會在同一個主要存放區中執行。這項服務 包含主要存放區和所有已定義外部存放區。

請注意,以往「存放區」的概念和「工作區」已經 混淆;「workspace」一詞經常用來指稱 有時甚至會用作「存放區」的同義詞

標準存放區名稱

存放區可定址的正規名稱,在 工作區,每個存放區都有一個正式名稱。存放區中的目標 標籤的標準名稱為 canonical_name @@canonical_name//package:target (請注意雙精度 @)。

主要存放區一律以空字串做為標準名稱。

顯示的存放區名稱

存放區名稱可透過其他特定存放區來定址。 這可以視為存放區的「nickname」:含有標準名稱的存放區 michael 在存放區中可能有名為 mike 的顯示名稱 alice,但存放區中的顯示名稱可能有 mickeybob。在此情況下,標籤可以處理 michael 內的目標 以 alice 為基準的 @mike//package: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 建立的依附元件圖表 模組。

使用 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 取決於 BCBC 都依附於不同版本的 D)。

由於 WORKSPACE 方面的缺點,Bzlmod 會把舊版資料 WORKSPACE 系統,用於日後的 Bazel 版本。請參閱 Bzlmod 遷移 指南