Bazel は、ビルドで使用される、ワークスペース以外の外部依存関係であるソースファイル(テキストとバイナリの両方)をサポートしています。たとえば、GitHub リポジトリでホストされているルールセット、Maven アーティファクト、現在のワークスペース外のローカルマシン上のディレクトリなどがあります。
Bazel 6.0 以降、Bazel で外部依存関係を管理する方法は 2 つあります。リポジトリを重視した従来の WORKSPACE
システムと、モジュールを重視した新しい MODULE.bazel
システム(コードネーム Bzlmod、--enable_bzlmod
フラグで有効化)です。この 2 つのシステムは併用できますが、今後の Bazel リリースで 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
ターゲットとして使用できるようにする」、「ローカル ディレクトリにシンボリック リンクする」などがあります。すべてのリポジトリは、適切な数の引数でリポジトリ ルールを呼び出すことで定義されます。
独自のリポジトリ ルールを記述する方法について詳しくは、リポジトリのルールをご覧ください。
最も一般的なリポジトリルールは、URL からアーカイブをダウンロードして抽出する http_archive
と、すでに Bazel リポジトリにあるローカル ディレクトリにシンボリック リンクを設定する local_repository
です。
リポジトリを取得する
関連するリポジトリルールを実行して、リポジトリをローカル ディスクで利用可能にするアクション。ワークスペースで定義されたリポジトリは、取得前にローカル ディスクで使用できません。
通常、Bazel は、リポジトリから何かが必要で、リポジトリがまだフェッチされていない場合にのみ、リポジトリを取得します。リポジトリがすでにフェッチされている場合、Bazel は定義が変更された場合にのみ、リポジトリを再フェッチします。
ディレクトリ レイアウト
取得されたリポジトリは、正規名で出力ベースのサブディレクトリ external
に配置されます。
次のコマンドを実行して、正規名 canonical_name
のリポジトリの内容を表示できます。
ls $(bazel info output_base)/external/ canonical_name
Bzlmod で外部依存関係を管理する
新しい外部依存関係サブシステムの Bzlmod は、リポジトリの定義で直接動作しません。代わりに、モジュールから依存関係グラフを作成し、グラフ上で拡張機能を実行して、それに応じてリポジトリを定義します。
Bazel モジュールは、複数のバージョンを持つことができる 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 レジストリ(デフォルトでは Bazel Central Registry)で検索します。このレジストリには依存関係の MODULE.bazel
ファイルが用意されています。これにより、バージョン解決を実行する前に、Bazel が推移的な依存関係グラフ全体を検出できます。
バージョンの解決(モジュールごとに 1 つのバージョンが選択)の後、Bazel はレジストリを再度参照し、各モジュールのリポジトリを定義する方法を確認します(通常は http_archive
を使用します)。
モジュールでは、タグと呼ばれるカスタマイズされたデータを指定することもできます。タグは、モジュールの解決後にモジュール拡張機能によって使用され、追加のリポジトリを定義します。これらの拡張機能はリポジトリ ルールに似た機能を備えており、ファイルの I/O やネットワーク リクエストの送信などのアクションを実行できます。特に、Bazel による他のパッケージ管理システムとのやり取りが可能になる一方で、Bazel モジュールから構築された依存関係グラフも考慮されます。
Bzlmod の外部リンク
- bazelbuild/examples での bzlmod の使用例
- Bazel の外部依存関係の見直し(元の Bzlmod 設計ドキュメント)
- BazelCon 2021 での Bzlmod についての講演
- Bazel コミュニティ デーの 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
システムの欠点
WORKSPACE
システムが導入されてから数年にわたり、ユーザーから次のような多くの課題が報告されています。
- Bazel は依存関係の
WORKSPACE
を評価しません。そのため、直接的な依存関係だけでなく、すべての推移的な依存関係をメイン リポジトリのWORKSPACE
ファイルで定義する必要があります。 - この問題を回避するため、プロジェクトでは「deps.bzl」パターンを採用しています。このパターンでは、複数のリポジトリを定義するマクロを定義し、
WORKSPACE
ファイルでこのマクロを呼び出すようユーザーに求めています。- これには固有の問題があります。マクロは他の
.bzl
ファイルをload
できないので、これらのプロジェクトでは、この「deps」マクロで推移的な依存関係を定義するか、ユーザーが複数のレイヤの「deps」マクロを呼び出すようにしてこの問題を回避する必要があります。 - Bazel は
WORKSPACE
ファイルを順番に評価します。また、依存関係はhttp_archive
を使用して URL とともに指定します。バージョン情報は必要ありません。つまり、ダイヤモンド依存関係の場合にバージョン解決を行うための信頼できる方法がありません(A
はB
とC
に依存し、B
とC
は両方ともD
のバージョンに依存します)。
- これには固有の問題があります。マクロは他の
WORKSPACE の欠点により、今後の Bazel リリースでは、Bzlmod が従来の WORKSPACE システムを置き換える予定です。Bzlmod に移行する方法については、Bzlmod 移行ガイドをご覧ください。