外部依存関係の概要

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 コマンドで共有される環境は、同じメイン リポジトリで実行されます。

歴史的に、「リポジトリ」と「ワークスペース」の概念は混同されてきました。「ワークスペース」という用語は、メイン リポジトリを指すためによく使用され、「リポジトリ」の同義語として使用されることもあります。

正規リポジトリ名

リポジトリがアドレス指定できる正規名。ワークスペースのコンテキスト内で、各リポジトリには単一の正規名があります。正規名が 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 はレジストリを再度参照し、モジュールごとにリポジトリを定義する方法を確認します(ほとんどの場合、http_archive を使用します)。

モジュールでは、タグと呼ばれるカスタマイズされたデータも指定できます。このタグは、モジュールの解決後にモジュール拡張機能によって使用され、追加のリポジトリを定義します。これらの拡張機能には、リポジトリ ルールと同様の機能があり、ファイル I/O やネットワーク リクエストの送信などのアクションを実行できます。特に、Bazel モジュールから構築された依存関係グラフを尊重しながら、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 の repo を定義します。WORKSPACE システムでは、デフォルトで、リポジトリの正規名は他のすべてのリポジトリに対する表示名でもあります。

WORKSPACE システムの欠点

WORKSPACE システムが導入されてから数年の間に、ユーザーから次のような多くの問題が報告されています。

  • Bazel は依存関係の WORKSPACE ファイルを評価しないため、直接依存関係に加えて、すべての伝播依存関係をメイン リポジトリの WORKSPACE ファイルで定義する必要があります。
  • この問題を回避するために、プロジェクトは「deps.bzl」パターンを採用しています。このパターンでは、複数のリポジトリを定義するマクロを定義し、ユーザーに WORKSPACE ファイルでこのマクロを呼び出すよう求めます。
    • これには独自の問題があります。マクロは他の .bzl ファイルを load できないため、これらのプロジェクトは、この「deps」マクロで伝播依存関係を定義するか、ユーザーが複数のレイヤ化された「deps」マクロを呼び出すようにすることで、この問題を回避する必要があります。
    • Bazel は WORKSPACE ファイルを順番に評価します。また、依存関係は、バージョン情報なしで URL とともに http_archive を使用して指定します。つまり、ダイヤモンド依存関係の場合にバージョン解決を行う信頼できる方法がありません(ABC に依存し、BCD の異なるバージョンに依存します)。

WORKSPACE の欠点により、今後の Bazel リリースでは、Bzlmod が従来の WORKSPACE システムに代わる予定です。Bzlmod への移行方法については、Bzlmod 移行ガイドをご覧ください。