Bazel は、ワークスペースにないビルドで使用されるソースファイル(テキストとバイナリの両方)である外部依存関係をサポートしています。 たとえば、GitHub リポジトリでホストされているルールセット、Maven アーティファクト、現在のワークスペース外のローカルマシンのディレクトリなどがあります。
Bazel 6.0 以降、Bazel で外部依存関係を管理する方法は 2 つあります。
従来のリポジトリ中心の WORKSPACE システムと、
新しいモジュール中心の MODULE.bazel システム(コードネーム Bzlmod、
フラグ --enable_bzlmod で有効)です。2 つのシステムを
併用できますが、今後の Bazel
リリースでは Bzlmod が WORKSPACE システムに置き換わります。移行方法については、Bzlmod 移行ガイドをご覧ください。
このドキュメントでは、Bazel での外部依存関係の管理に関するコンセプトについて説明し、2 つのシステムについて詳しく説明します。
コンセプト
リポジトリ
WORKSPACE ファイルまたは WORKSPACE.bazel ファイルを含むディレクトリ。Bazel ビルドで使用されるソース
ファイルが含まれています。多くの場合、リポジトリ と略されます。
メイン リポジトリ
現在の Bazel コマンドが実行されているリポジトリ。
ワークスペース
同じメイン リポジトリで実行されるすべての Bazel コマンドで共有される環境。
歴史的に、「リポジトリ」と「ワークスペース」のコンセプトは混同されてきました。「ワークスペース」という用語は、メイン リポジトリを指すために使用されることが多く、リポジトリの同義語として使用されることもありました。
正規リポジトリ名
リポジトリがアドレス指定可能な正規名。ワークスペースのコンテキスト内では、各リポジトリに 1 つの正規名があります。正規名が canonical_name のリポジトリ内のターゲットは、ラベル
@@canonical_name//pac/kage:target でアドレス指定できます(二重の @ に注意してください)。
メイン リポジトリの正規名は常に空の文字列です。
表示リポジトリ名
特定のリポジトリのコンテキストでリポジトリがアドレス指定可能な名前。
これはリポジトリの「ニックネーム」と考えることができます。正規名が michael のリポジトリは、リポジトリ alice のコンテキストでは表示名が mike になる可能性がありますが、リポジトリ bob のコンテキストでは表示名が mickey になる可能性があります。この場合、michael 内のターゲットは、alice のコンテキストでラベル
@mike//pac/kage:target でアドレス指定できます(単一の @ に注意してください)。
逆に、これはリポジトリ マッピングと考えることができます。各リポジトリは 、「表示リポジトリ名」から「正規リポジトリ名」へのマッピングを維持します。
リポジトリ ルール
リポジトリ定義のスキーマ。Bazel にリポジトリを具体化する方法を指示します。たとえば、「特定の URL から ZIP アーカイブをダウンロードして展開する」、「特定の Maven アーティファクトを取得して java_import ターゲットとして使用できるようにする」、「ローカル ディレクトリをシンボリック リンクする」などがあります。すべてのリポジトリは、適切な数の引数を使用してリポジトリ ルールを呼び出すことで定義 されます。
独自のリポジトリ ルールの作成方法について詳しくは、リポジトリ ルールをご覧ください。
最も一般的なリポジトリ ルールは
http_archive(URL からアーカイブをダウンロードして展開)と
local_repository(すでに Bazel リポジトリであるローカル ディレクトリをシンボリック リンク)です。
リポジトリを取得する
関連付けられたリポジトリ ルールを実行して、リポジトリをローカル ディスクで使用できるようにするアクション。ワークスペースで定義されたリポジトリは、取得されるまでローカル ディスクで使用できません。
通常、Bazel はリポジトリから何かが必要で、リポジトリがまだ取得されていない場合にのみリポジトリを取得します。リポジトリがすでに取得されている場合、Bazel は定義が変更された場合にのみ再取得します。
ディレクトリ レイアウト
取得後、リポジトリは出力ベースの external サブディレクトリに正規名で保存されます。
次のコマンドを実行すると、正規名が canonical_name のリポジトリの内容を確認できます。
ls $(bazel info output_base)/external/ canonical_name Bzlmod で外部依存関係を管理する
新しい外部依存関係サブシステムである Bzlmod は、リポジトリ定義を直接操作しません。代わりに、モジュールから依存関係グラフを作成し、グラフの上に 拡張機能を実行して、それに応じてリポジトリを定義します。
A Bazel module は、複数の
バージョンを持つことができる Bazel プロジェクトです。各バージョンは、依存する他のモジュールに関するメタデータを公開
します。モジュールには、WORKSPACE ファイルの横にあるリポジトリのルートに MODULE.bazel ファイルが必要です。このファイルはモジュールのマニフェストで、名前、バージョン、依存関係のリストなどの情報が宣言されています。基本的な例を次に示します。
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 Central
Registry である
Bazel registryで直接依存関係を検索します。レジストリは依存関係の MODULE.bazel ファイルを提供します。これにより、Bazel はバージョン解決を実行する前に、推移的な依存関係グラフ全体を検出できます。
バージョン解決後(各モジュールに 1 つのバージョンが選択されます)、Bazel はレジストリを再度参照して、各モジュールのリポジトリを定義する方法(ほとんどの場合、http_archive を使用)を確認します。
モジュールは、モジュール解決後にモジュール拡張機能によって使用されるタグと呼ばれるカスタマイズされたデータの一部を指定することもできます。これにより、追加のリポジトリを定義できます。これらの拡張機能はリポジトリ ルールと同様の機能を備えており、ファイル I/O やネットワーク リクエストの送信などのアクションを実行できます。これにより、Bazel は他のパッケージ管理システムと連携しながら、Bazel モジュールから構築された依存関係グラフを尊重できます。
Bzlmod の外部リンク
- bazelbuild/examples の Bzlmod の使用例
- Bazel の外部依存関係の刷新 (元の Bzlmod 設計ドキュメント)
- BazelCon 2021 の Bzlmod に関する講演
- Bazel Community Day の Bzlmod に関する講演
WORKSPACE でリポジトリを定義する
従来、
WORKSPACE(または WORKSPACE.bazel)ファイルでリポジトリを定義することで、外部依存関係を管理できます。このファイルは BUILD ファイルと同様の構文を持ち、ビルドルールの代わりにリポジトリ ルールを使用します。
次のスニペットは、WORKSPACE ファイルで http_archive リポジトリ ルールを使用する例です。
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 システムが導入されて以来、ユーザーから多くの問題点が報告されています。たとえば、次のようなものがあります。
- Bazel は依存関係の
WORKSPACEファイルを評価しないため、直接依存関係に加えて、すべての推移的な依存関係をメイン リポジトリのWORKSPACEファイルで定義する必要があります。 - この問題を回避するため、プロジェクトでは「deps.bzl」パターンが採用されています。このパターンでは、複数のリポジトリを定義するマクロを定義し、ユーザーに
WORKSPACEファイルでこのマクロを呼び出すように依頼します。- これには独自の問題があります。マクロは他の
.bzlファイルをloadできないため、これらのプロジェクトでは、この「deps」マクロで推移的な依存関係を定義するか、ユーザーに複数の階層化された「deps」マクロを呼び出させることでこの問題を回避する必要があります。 - Bazel は
WORKSPACEファイルを順番に評価します。また、依存関係はバージョン情報なしで URL を使用してhttp_archiveで指定されます。つまり、ダイヤモンド依存関係(AがBとCに依存し、BとCが両方ともDの異なるバージョンに依存する)の場合、バージョン解決を確実に行う方法はありません。
- これには独自の問題があります。マクロは他の
WORKSPACE の欠点により、今後の Bazel リリースでは、Bzlmod が従来の WORKSPACE システムに置き換わります。Bzlmod への移行方法については、Bzlmod 移行 ガイドをご覧ください。