ベンダーモードは、外部依存関係のローカルコピーを作成できる Bzlmod の機能です。これは、オフライン ビルドや、外部依存関係のソースを制御する場合に便利です。
ベンダーモードを有効にする
ベンダーモードを有効にするには、--vendor_dir
フラグを指定します。
たとえば、.bazelrc
ファイルに追加します。
# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src
ベンダー ディレクトリは、ワークスペースのルートへの相対パスまたは絶対パスにすることができます。
特定の外部リポジトリをベンダリングする
--repo
フラグを指定して vendor
コマンドを使用すると、ベンダーにどのリポジトリを配布するかを指定できます。このコマンドでは、正規リポジトリ名と見かけのリポジトリ名の両方を指定できます。
たとえば、次のコマンドを実行します。
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
または
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
どちらも、rules_cc が <workspace root>/vendor_src/rules_cc+
の下にベンダー化されます。
指定されたターゲットに対するベンダー外部依存関係
特定のターゲット パターンのビルドに必要なすべての外部依存関係をベンダーに登録するには、bazel vendor <target patterns>
を実行します。
次に例を示します。
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
は、//src/main:hello-world
ターゲットのビルドに必要なすべてのリポジトリと、現在の構成で //src/test/...
の下のすべてのターゲットをベンダー化します。
内部的には、bazel build --nobuild
コマンドが実行されてターゲット パターンが分析されるため、このコマンドにビルドフラグを適用して結果に影響を与える可能性があります。
ターゲットをオフラインでビルドする
外部依存関係をベンダリングしたら、次の方法でターゲットをオフラインでビルドできます。
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
ビルドは、ネットワーク アクセスとリポジトリ キャッシュのないクリーンなビルド環境で動作する必要があります。
したがって、ベンダー提供のソースをチェックインし、別のマシンでオフラインで同じターゲットをビルドできる必要があります。
すべての外部依存関係をベンダリングする
伝播外部依存関係グラフ内のすべてのリポジトリをベンダー化するには、次のコマンドを実行します。
bazel vendor --vendor_dir=vendor_src
すべての依存関係をベンダリングすることには、いくつかのデメリットがあります。
- 推移的に導入されたリポジトリを含むすべてのリポジトリの取得には時間がかかる場合があります。
- vendor ディレクトリは非常に大きくなる可能性があります。
- 一部のリポジトリは、現在のプラットフォームまたは環境と互換性がないと取得に失敗することがあります。
そのため、まず特定のターゲットのベンダリングを検討してください。
VENDOR.bazel を使用してベンダーモードを構成する
特定のリポジトリの処理方法は、ベンダー ディレクトリにある VENDOR.bazel ファイルで制御できます。
使用できるディレクティブは 2 つあり、どちらも正規リポジトリ名のリストを引数として受け入れます。
ignore()
: ベンダーモードからリポジトリを完全に無視します。pin()
: このリポジトリに--override_repository
フラグがある場合と同様に、現在のベンダリングされたソースにリポジトリを固定します。Bazel は、固定を解除しない限り、vendor コマンドを実行している間、このリポジトリのベンダリングされたソースを更新しません。ユーザーは、このリポジトリのベンダー提供ソースを手動で変更して維持できます。
次に例を示します。
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
この構成では
- どちらのリポジトリも、後続のベンダー コマンドから除外されます。
- Repo
bazel_skylib
は、ベンダー ディレクトリの下のソースにオーバーライドされます。 - ユーザーは
bazel_skylib
のベンダー提供ソースを安全に変更できます。 bazel_skylib
を再ベンダー化するには、まずピン ステートメントを無効にする必要があります。
ベンダーモードの仕組みを理解する
Bazel は、$(bazel info
output_base)/external
にあるプロジェクトの外部依存関係を取得します。外部依存関係をベンダー化すると、関連するファイルとディレクトリを指定されたベンダー ディレクトリに移動し、後続のビルドにベンダー化されたソースを使用できます。
ベンダー提供のコンテンツには、次のものがあります。
- リポジトリ ディレクトリ
- リポジトリ マーカー ファイル
ビルド中に、ベンダリングされたマーカー ファイルが最新であるか、リポジトリが VENDOR.bazel ファイルに固定されている場合、Bazel は実際にリポジトリ ルールを実行する代わりに、$(bazel info output_base)/external
の下にベンダリングされたソースへのシンボリック リンクを作成して、ベンダリングされたソースを使用します。それ以外の場合は、警告が印刷され、Bazel は最新バージョンのリポジトリの取得にフォールバックします。
ベンダーのレジストリ ファイル
Bazel は外部依存関係を取得するために Bazel モジュール解決を実行する必要があります。この場合、インターネット経由でレジストリ ファイルにアクセスすることが必要になる場合があります。オフライン ビルドを実現するために、Bazel はネットワークから取得したすべてのレジストリ ファイルを <vendor_dir>/_registries
ディレクトリに保存します。
ベンダー シンボリック リンク
外部リポジトリには、他のファイルまたはディレクトリを指すシンボリック リンクが含まれている場合があります。シンボリック リンクが正しく機能するように、Bazel は次の戦略を使用してベンダー提供ソースのシンボリック リンクを書き換えます。
$(bazel info output_base)/external
を指すシンボリック リンク<vendor_dir>/bazel-external
を作成します。これは、すべての Bazel コマンドによって自動的に更新されます。- ベンダリングされたソースの場合は、元々
$(bazel info output_base)/external
の下のパスを指していたすべてのシンボリック リンクを<vendor_dir>/bazel-external
の下の相対パスに書き換えます。
たとえば、元のシンボリック リンクが
<vendor_dir>/repo_foo+/link => $(bazel info output_base)/external/repo_bar+/file
次の新しいルールに書き換えられます:
<vendor_dir>/repo_foo+/link => ../../bazel-external/repo_bar+/file
ここで
<vendor_dir>/bazel-external => $(bazel info output_base)/external # This might be new if output base is changed
<vendor_dir>/bazel-external
は Bazel によって自動的に生成されるため、チェックインを回避するために .gitignore
または同等のファイルに追加することをおすすめします。
この戦略では、ベンダー提供ソースが別の場所に移動された後や、Bazel の出力ベースが変更された後でも、ベンダー提供ソースのシンボリック リンクが正しく機能します。