供應商模式是 Bzlmod 的一項功能,可讓您建立外部依附元件的本機副本。這項功能適用於離線建構作業,或您想控管外部依附元件的來源時。
啟用供應商模式
您可以指定 --vendor_dir
旗標來啟用供應商模式。
例如,將檔案新增至 .bazelrc
檔案即可:
# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src
供應商目錄可以是工作區根目錄的相對路徑,也可以是絕對路徑。
供應商特定外部存放區
您可以使用 vendor
指令搭配 --repo
旗標來指定要供應商的存放區,此指令可接受標準存放區名稱和 apparent 存放區名稱。
舉例來說,您可以執行:
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
或
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc~
都會使規則_cc 併入 <workspace root>/vendor_src/rules_cc~
之下。
指定目標的供應商外部依附元件
如要廠商建構指定目標模式所需的所有外部依附元件,您可以執行 bazel vendor <target patterns>
。
範例說明
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
供應商會提供建構 //src/main:hello-world
目標所需的所有 repos,以及 //src/test/...
下所有目標的目前設定。
實際上,系統會執行 bazel build --nobuild
指令來分析目標模式,因此建構標記可套用至這個指令,進而影響結果。
離線建立目標
有了外部供應商的依附元件,您可以透過以下方式離線建構目標:
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
建構作業應可在沒有網路存取權和存放區快取的情況下,在乾淨的建構環境中運作。
因此,您應該可以檢查廠商來源,並在另一台機器上離線建構相同的目標。
供應商所有外部依附元件
如要廠商轉換外部依附元件圖表中的所有存放區,您可以執行下列指令:
bazel vendor --vendor_dir=vendor_src
請注意,廠商所有依附元件有幾個缺點:
- 擷取所有存放區 (包括間接引入的存放區) 可能會耗時。
- 供應商目錄可能會變得非常大。
- 如果部分存放區與目前平台或環境不相容,可能無法擷取。
因此,建議您優先考量特定目標。
使用 VENDOR.bazel 設定供應商模式
您可以透過供應商目錄下的 VENDOR.bazel 檔案,控制如何處理特定存放區。
您可以使用兩種指令,兩者都接受標準存放區名稱清單做為引數:
ignore()
:從供應商模式完全忽略存放區。pin()
:將存放區釘選至其目前的供應商來源,就像這個存放區有--override_repository
標記一樣。除非未固定,否則 Bazel 在執行供應商指令時,「不會」更新這個存放區的廠商來源。使用者可以手動修改及維護這個存放區的廠商原始碼。
範例說明
ignore("@@rules_cc~")
pin("@@bazel_skylib~")
使用這項設定
- 後續供應商指令將排除這兩個存放區。
- Repo
bazel_skylib
會覆寫為供應商目錄下方的來源。 - 使用者可以安全地修改供應商來源
bazel_skylib
。 - 如要重新供應商
bazel_skylib
,使用者必須先停用 PIN 碼陳述式。
瞭解供應商模式的運作方式
Bazel 會擷取 $(bazel info
output_base)/external
底下專案的外部依附元件。供應商外部依附元件是指將相關檔案和目錄移出指定的廠商目錄,並在後續建構中使用供應商的來源。
廠商的內容包括:
- 存放區目錄
- 存放區標記檔案
在建構期間,如果廠商的標記檔案為最新版本,或存放區已在 VENDOR.bazel 檔案中固定,則 Bazel 會在 $(bazel info output_base)/external
下建立指向該檔案的符號連結,而非實際執行存放區規則,藉此使用供應商的來源。否則,系統會顯示警告,然後 Bazel 會回頭擷取最新版本的存放區。
供應商登錄檔案
Bazel 必須執行 Bazel 模組解析,才能擷取外部依附元件,不過可能需要透過網際網路存取登錄檔案。為了達成離線建構,Bazel 供應商會從網路擷取的所有登錄檔案,並儲存在 <vendor_dir>/_registries
目錄下。
供應商符號連結
外部存放區可能包含指向其他檔案或目錄的符號連結。為確保符號連結可正常運作,Bazel 會採用以下策略,重新編寫供應商來源中的符號連結:
- 建立指向
$(bazel info output_base)/external
的符號連結<vendor_dir>/bazel-external
。每個 Bazel 指令都會自動重新整理這個檔案。 - 針對供應商來源,將所有原本指向
$(bazel info output_base)/external
下路徑的符號連結,重寫為<vendor_dir>/bazel-external
下相對路徑。
舉例來說,如果原始符號連結
<vendor_dir>/repo_foo~/link => $(bazel info output_base)/external/repo_bar~/file
日後將重新寫入
<vendor_dir>/repo_foo~/link => ../../bazel-external/repo_bar~/file
媒介
<vendor_dir>/bazel-external => $(bazel info output_base)/external # This might be new if output base is changed
由於 <vendor_dir>/bazel-external
是由 Bazel 自動產生,建議您將其新增至 .gitignore
或等效項目,以免將其簽入。
採用這項策略後,即使供應商來源已移至其他位置或 Bazel 輸出基地已變更,供應商來源中的符號連結仍應能正常運作。