外部依存関係の概要

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
問題を報告する ソースを表示

Bazel は、外部依存関係と、ワークスペース以外からビルドで使用されるソースファイル(テキストとバイナリの両方)をサポートします。たとえば、GitHub リポジトリ、Maven アーティファクト、現在のワークスペース外のローカルマシン上のディレクトリでホストされているルールセットなどです。

Bazel 6.0 では、Bazel で外部依存関係を管理するには、従来のリポジトリを重視した WORKSPACE システムと、新しいモジュールに焦点を当てた MODULE.bazel システム(コード名は Bzlmod、フラグ --enable_bzlmod が有効)の 2 つの方法があります。これらの 2 つのシステムを同時に使用することもできますが、今後の Bazel リリースでは Bzlmod が WORKSPACE システムに置き換えられます。

この記事では、Bazel での外部依存関係の管理のコンセプトについて説明してから、2 つのシステムを順番に詳しく説明します。

コンセプト

リポジトリ

Bazel ビルドで使用されるソースファイルを含む WORKSPACE または WORKSPACE.bazel ファイルがあるディレクトリ。「repo」と短縮されることが多いです。

メイン リポジトリ

現在の Bazel コマンドが実行されているリポジトリ。

ワークスペース

すべての Bazel コマンドで共有される環境は、同じメイン リポジトリで実行されます。

「リポジトリ」と「ワークスペース」という概念はこれまで混同されてきました。多くの場合、「ワークスペース」という用語はメイン リポジトリを指す用語として用いられており、「リポジトリ」の同義語として使用されることもあります。

正規リポジトリ名

リポジトリがアドレス指定するための正規名。ワークスペースのコンテキスト内では、各リポジトリに 1 つの正規名があります。正規名が canonical_name であるリポジトリ内のターゲットは、@@canonical_name//pac/kage:target ラベルで指定できます(@ が 2 つ重複しています)。

メイン リポジトリでは、正規名として常に空の文字列が使用されます。

Apparent リポジトリ名

リポジトリのアドレス指定が可能なリポジトリ名。これは、リポジトリの「ニックネーム」と考えることができます。正規名 michael のリポジトリは、リポジトリ alice のコンテキストでは mike という名前になりますが、bob 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 モジュールから作成された依存関係グラフを尊重できます。

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 システムの導入から数年が経過し、多くの問題点が報告されています。

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