Bazel は、外部依存関係、つまりワークスペースのものではなく、ビルドで使用されるソースファイル(テキストとバイナリの両方)をサポートしています。たとえば、GitHub リポジトリでホストされているルールセット、Maven アーティファクト、現在のワークスペース外のローカルマシンのディレクトリなどです。
Bazel 6.0 では、Bazel で外部依存関係を管理する方法が 2 つあります。リポジトリを重視した従来の WORKSPACE
システムと、モジュールを重視した新しい MODULE.bazel
システム(コード名 Bzlmod、フラグ --enable_bzlmod
で有効化)です。この 2 つのシステムは併用できますが、今後の Bazel リリースで WORKSPACE
システムを置き換える方法については、Bzlmod} で移行に関するガイドをご覧ください。{/Bzlmod}
このドキュメントでは、2 つのシステムについて順番に詳しく説明する前に、Bazel での外部依存関係の管理に関するコンセプトについて説明します。
コンセプト
リポジトリ
WORKSPACE
ファイルまたは WORKSPACE.bazel
ファイルを含むディレクトリ。Bazel ビルドで使用されるソースファイルが含まれています。多くの場合、リポのために短縮されます。
メイン リポジトリ
現在の Bazel コマンドが実行されているリポジトリ。
ワークスペース
すべての Bazel コマンドで共有される環境は、同じメイン リポジトリで実行されます。
これまで、「リポジトリ」と「ワークスペース」のコンセプトは混同されてきました。「ワークスペース」という用語はメイン リポジトリを指すために使用され、場合によっては「リポジトリ」の同義語として使用されることさえあります。
正規リポジトリ名
リポジトリがアドレス指定できる正規名。ワークスペースのコンテキスト内で、各リポジトリには単一の正規名があります。正規名が canonical_name
の repo 内のターゲットは、ラベル @@canonical_name//pac/kage:target
で参照できます(@
が 2 つあることに注意してください)。
メイン リポジトリの正規名は常に空の文字列です。
わかりやすいリポジトリ名
リポジトリの名前。他のリポジトリのコンテキストで参照できます。これはリポジトリの「ニックネーム」と考えることができます。正規名が 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 はレジストリに再度問い合わせて、各モジュールの repo を定義する方法を学習します(ほとんどの場合、http_archive
を使用します)。
モジュールでは、タグと呼ばれるカスタマイズされたデータも指定できます。このタグは、モジュールの解決後にモジュール拡張機能によって使用され、追加のリポジトリを定義します。これらの拡張機能にはリポジトリ ルールに似た機能があり、ファイル I/O やネットワーク リクエストの送信などのアクションを実行できます。たとえば、Bazel は Bazel モジュールから構築された依存関係グラフを尊重しながら、他のパッケージ管理システムとやり取りできます。
Bzlmod の外部リンク
- bazelbuild/examples での Bzlmod の使用例
- Bazel 外部依存関係の刷新(元の Bzlmod 設計ドキュメント)
- Bzlmod に関する BazelCon 2021 の講演
- Bzlmod に関する Bazel Community Day のトーク
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
の repo を定義します。WORKSPACE
システムでは、デフォルトでリポジトリの正規名が他のすべてのリポジトリに見える名前になります。
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 の欠点により、Bzlmod は今後の Bazel リリースで以前の WORKSPACE システムを置き換えようとしています。Bzlmod への移行方法については、Bzlmod 移行ガイドをご覧ください。