Bazel は、ワークスペースにないビルドで使用される外部依存関係、ソースファイル(テキストとバイナリの両方)をサポートしています。たとえば、GitHub リポジトリでホストされているルールセット、Maven アーティファクト、現在のワークスペース外のローカルマシンのディレクトリなどです。
Bazel 6.0 以降では、Bazel で外部依存関係を管理する方法が 2 つあります。従来のリポジトリ中心の WORKSPACE
システムと、新しいモジュール中心の MODULE.bazel
システム(コードネーム Bzlmod、フラグ --enable_bzlmod
で有効)。2 つのシステムを一緒に使用できますが、Bzlmod は今後の Bazel リリースで WORKSPACE
システムに置き換わります。移行方法については、Bzlmod 移行ガイドをご覧ください。
このドキュメントでは、Bazel での外部依存関係の管理に関するコンセプトについて説明してから、2 つのシステムについて順に詳しく説明します。
コンセプト
リポジトリ
WORKSPACE
ファイルまたは WORKSPACE.bazel
ファイルを含むディレクトリ。Bazel ビルドで使用されるソースファイルが含まれています。多くの場合、単に repo と短縮されます。
メイン リポジトリ
現在の Bazel コマンドが実行されているリポジトリ。
ワークスペース
すべての Bazel コマンドで共有される環境は、同じメイン リポジトリで実行されます。
これまで、「リポジトリ」と「ワークスペース」の概念が混同されてきたことに注意してください。「ワークスペース」という用語は、メイン リポジトリを指すために使用されることが多く、場合によっては「リポジトリ」の同義語として使用されることもあります。
正規リポジトリ名
リポジトリがアドレス指定可能な正規名。ワークスペースのコンテキスト内では、各リポジトリに 1 つの正規名があります。正規名が canonical_name
のリポジトリ内のターゲットは、ラベル @@canonical_name//pac/kage:target
でアドレス指定できます(@
が 2 つあることに注意してください)。
メイン リポジトリの正規名は常に空の文字列です。
リポジトリの表示名
特定のリポジトリのコンテキストでリポジトリがアドレス指定可能な名前。これは、リポジトリの「ニックネーム」と考えることができます。正規名 michael
のリポジトリは、リポジトリ alice
のコンテキストでは mike
という名前で表示されることがありますが、リポジトリ bob
のコンテキストでは mickey
という名前で表示されることがあります。この場合、michael
内のターゲットは、alice
のコンテキストでラベル @mike//pac/kage:target
によってアドレス指定できます(@
は 1 つだけです)。
逆に、これはリポジトリ マッピングと考えることもできます。各リポジトリは、「見かけ上のリポジトリ名」から「正規のリポジトリ名」へのマッピングを保持します。
リポジトリ ルール
リポジトリを具体化する方法を Bazel に伝えるリポジトリ定義のスキーマ。たとえば、「特定の URL から zip アーカイブをダウンロードして展開する」、「特定の Maven アーティファクトを取得して java_import
ターゲットとして使用できるようにする」、「ローカル ディレクトリをシンボリック リンクする」などです。すべてのリポジトリは、適切な数の引数を使用してリポジトリルールを呼び出すことで定義されます。
独自のリポジトリルールを作成する方法については、リポジトリルールをご覧ください。
最も一般的な repo ルールは、URL からアーカイブをダウンロードして抽出する http_archive
と、すでに Bazel リポジトリであるローカル ディレクトリをシンボリック リンクする local_repository
です。
リポジトリをフェッチする
関連付けられた repo ルールを実行して、ローカル ディスクで repo を使用可能にするアクション。ワークスペースで定義されたリポジトリは、取得されるまでローカル ディスクで使用できません。
通常、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
を使用)を確認します。
モジュールは、タグと呼ばれるカスタマイズされたデータの一部を指定することもできます。これは、モジュール解決後に モジュール拡張機能によって使用され、追加のリポジトリを定義します。これらの拡張機能は repo ルールと同様の機能を備えており、ファイル I/O やネットワーク リクエストの送信などのアクションを実行できます。これらにより、Bazel モジュールから構築された依存関係グラフを尊重しながら、Bazel が他のパッケージ管理システムとやり取りできるようになります。
Bzlmod の外部リンク
- bazelbuild/examples の Bzlmod の使用例
- Bazel 外部依存関係のオーバーホール(元の Bzlmod 設計ドキュメント)
- Bzlmod に関する BazelCon 2021 の講演
- Bzlmod に関する Bazel コミュニティ デーの講演
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 移行ガイドをご覧ください。