ベンダーモードは、外部依存関係のローカルコピーを作成できる機能です。これは、オフライン ビルドの場合や、外部依存関係のソースを制御する場合に便利です。
ベンダーモードを有効にする
ベンダーモードを有効にするには、--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+
は、どちらも <workspace root>/vendor_src/rules_cc+
でベンダーに提供される 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
フラグがあるかのように、リポジトリを現在のベンダー ソースに固定します。Bazel は、ベンダー コマンドの実行中に、このリポジトリのベンダー ソースを更新しません(ピン留めが解除されている場合を除く)。ユーザーは、このリポジトリのベンダー ソースを手動で変更および維持できます。
次に例を示します。
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
この構成では
- 両方のリポジトリが以降のベンダー コマンドから除外されます。
- Repo
bazel_skylib
は、vendor ディレクトリにあるソースにオーバーライドされます。 - ユーザーは
bazel_skylib
のベンダー提供ソースを安全に変更できます。 bazel_skylib
を再ベンダーするには、ユーザーはまず PIN ステートメントを無効にする必要があります。
ベンダーモードの仕組みを理解する
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 出力ベースが変更されたりしても、ベンダー提供のソース内のシンボリック リンクが正しく機能します。