Bazel は、ビルドで使用されるワークスペースの外部依存関係(テキストとバイナリの両方)である外部依存関係をサポートします。たとえば、GitHub リポジトリでホストされているルールセット、Maven アーティファクト、現在のワークスペース外のローカルマシンのディレクトリなどです。
WORKSPACE
WORKSPACE
MODULE.bazel
--enable_bzlmod
このドキュメントでは、2 つのシステムについて順番に詳しく説明する前に、Bazel での外部依存関係管理のコンセプトについて説明します。
コンセプト
リポジトリ
Bazel ビルドで使用するソースファイルを含む WORKSPACE
または WORKSPACE.bazel
ファイルを含むディレクトリ。「repo」と略されることもあります。
メイン リポジトリ
現在の Bazel コマンドが実行されているリポジトリ。
ワークスペース
すべての Bazel コマンドによって共有される環境は、同じメイン リポジトリで実行されます。
「リポジトリ」と「ワークスペース」という概念は従来から混同されています。「ワークスペース」という用語は、多くの場合、メイン リポジトリを指すことを指し、「リポジトリ」の同義語として使用されることもあります。
正規リポジトリ名
リポジトリが参照できる正規名。ワークスペースのコンテキスト内では、各リポジトリには単一の正規名があります。正規名が canonical_name
であるリポジトリ内のターゲットは、ラベル @@canonical_name//pac/kage:target
でアドレス指定できます(二重の @
に注意してください)。
メイン リポジトリは、常に正規名として空の文字列になります。
Apparent リポジトリ名
リポジトリのアドレスは、特定の他のリポジトリのコンテキストでアドレス指定できます。これはリポジトリの「ニックネーム」と考えることができます。正規の名前 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 セントラル レジストリ)。レジストリは依存関係の MODULE.bazel
ファイルを提供します。これにより、Bazel はバージョンの解決を行う前に、推移的な依存関係グラフ全体を検出できます。
バージョン解決(各モジュールに対して 1 つのバージョンが選択されている)の後、Bazel はレジストリに再度コンサルトし、各モジュールのリポジトリを定義する方法を学習します(ほとんどの場合、http_archive
を使用します)。
モジュールはタグと呼ばれるカスタマイズされたデータを指定することもできます。これは、モジュールの解決後にモジュール拡張機能で追加され、追加のリポジトリを定義します。これらの拡張機能には、リポジトリ ルールと同様の機能があり、ファイルの 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
ファイルを使用できないため、これらのプロジェクトでは、この「deps」マクロで推移的な依存関係を定義するか、ユーザーに複数の「依存関係」マクロを呼び出すようにして問題を回避する必要があります。load
- Bazel は
WORKSPACE
ファイルを順番に評価します。また、バージョン情報なしで、URL とともにhttp_archive
を使用して依存関係を指定します。つまり、ひし形の依存関係の場合、バージョン解決を行う信頼性の高い方法はありません(A
はB
とC
に依存し、B
とC
は異なるバージョンのD
に依存します)。
- これには独自の問題があり、マクロは他の
WORKSPACE の短所により、Bzlmod は、今後の Bazel リリースで従来の WORKSPACE システムを置き換える予定です。Bzlmod に移行する方法については、Bzlmod 移行ガイドをご覧ください。