外部依附元件總覽

回報問題 查看原始碼 夜間 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 指令的存放區。

工作區

所有 Bazel 指令共用的環境都會在同一個主要存放區中執行。

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

標準存放區名稱

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

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

顯示的存放區名稱

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

使用 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 遷移 指南