ベンダーモード

問題を報告する ソースを表示 ナイトリー · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

ベンダーモードを有効にするには、--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.bazel ファイルで制御できます。

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

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

次に例を示します。

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