ベンダーモード

ベンダーモードは、 外部依存関係のローカルコピーを作成できる機能です。これは、オフライン ビルドの場合や、外部依存関係のソースを 制御する場合に便利です。

ベンダーモードを有効にする

ベンダーモードを有効にするには、--vendor_dir フラグを指定します。

たとえば、.bazelrc ファイルに追加します。

# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src

ベンダー ディレクトリは、ワークスペース ルートへの相対パスまたは 絶対パスにできます。

特定の外部リポジトリをベンダリングする

vendor コマンドを --repo フラグとともに使用して、ベンダリングするリポジトリ を指定できます。正規のリポジトリ 名表示されるリポジトリ 名の両方を使用できます。

たとえば、次のコマンドを実行します。

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.bazel でベンダーモードを構成する

指定されたリポジトリの処理方法は、vendor ディレクトリにある VENDOR.bazel ファイルで制御できます。

2 つのディレクティブを使用できます。どちらも、 正規のリポジトリ名のリストを引数として受け取ります。

  • ignore(): ベンダーモードからリポジトリを完全に無視します。
  • pin(): このリポジトリに --override_repositoryフラグがあるかのように、リポジトリを現在のベンダリングされたソースに固定します。固定解除しない限り、ベンダー コマンドの実行中に、このリポジトリのベンダリングされた ソースは更新されません。 ユーザーは、このリポジトリのベンダリングされたソースを手動で変更して管理できます。

次に例を示します。

ignore("@@rules_cc+")
pin("@@bazel_skylib+")

この構成では

  • どちらのリポジトリも、以降のベンダー コマンドから除外されます。
  • リポジトリ bazel_skylib は、 vendor ディレクトリにあるソースにオーバーライドされます。
  • ユーザーは bazel_skylib のベンダリングされたソースを安全に変更できます。
  • bazel_skylib を再度ベンダリングするには、まず pin ステートメント を無効にする必要があります。
localconfigure

ベンダーモードの仕組みを理解する

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 出力ベース が変更されたりしても、ベンダリングされたソースのシンボリック リンクは正しく機能します。