リモート実行用に Bazel ルールを適用する

このページは、リモート実行に関する Bazel ルールの要件を理解し、カスタムビルドとテストルールを作成する Bazel ユーザーを対象としています。

リモート実行を使用すると、Bazel はデータセンターなどの別のプラットフォームでアクションを実行できます。Bazel は、リモート実行に gRPC プロトコルを使用します。分散リモート実行プラットフォームの提供を目的としたオープンソース プロジェクトである bazel-buildfarm を使用して、リモート実行を試すことができます。

このページでは、さまざまな環境タイプやプラットフォームを指す用語を使用します。

  • ホスト プラットフォーム - Bazel が実行される場所。
  • 実行プラットフォーム - Bazel アクションが実行されます。
  • ターゲット プラットフォーム - ビルド出力(および一部のアクション)が実行される場所。

概要

リモート実行用に Bazel ビルドを構成する場合は、このページで説明するガイドラインに従って、リモートからエラーなしでビルドを実行できるようにする必要があります。これは、リモート実行の性質によります。

  • 分離されたビルド アクション。ビルドツールは状態を保持せず、ツール間で依存関係がリークすることはありません。

  • 多様な実行環境。ローカルビルド構成は、必ずしもリモート実行環境に適しているわけではありません。

このページでは、リモート実行用の Bazel カスタム ビルドとテストルールの実装時に発生する可能性のある問題と、その回避方法について説明します。取り上げるトピックは次のとおりです。

ツールチェーン ルールによるビルドツールの呼び出し

Bazel ツールチェーン ルールは、使用するビルドツール(コンパイラやリンカーなど)と、ルールの作成者が定義したパラメータを使用してツールを構成する方法をビルドルールに指示する構成プロバイダです。ツールチェーン ルールを使用すると、ビルドルールとテストルールから、リモート実行と互換性のある、予測可能な事前構成された方法でビルドツールを呼び出すことができます。たとえば、PATHJAVA_HOME、またはリモート実行環境で同等の値に設定されていない(またはまったく)設定されていない可能性のある他のローカル変数を介してビルドツールを呼び出すのではなく、ツールチェーン ルールを使用します。

現在、ScalaRustGo の Bazel ビルドおよびテストルールに関するツールチェーン ルールが存在し、他の言語やツール(bash など)向けの新しいツールチェーン ルールが進行中です。 ルールで使用するツールにツールチェーン ルールが存在しない場合は、ツールチェーン ルールの作成を検討してください。

暗黙的な依存関係の管理

ビルドツールがビルド アクション間の依存関係にアクセスできる場合、各リモートビルド アクションは互いに独立して実行されるため、リモート実行時にこれらのアクションは失敗します。一部のビルドツールは、ツール呼び出しに明示的に含まれていないビルド アクションやアクセスの依存関係全体で状態を保持します。その場合、リモートで実行されたビルド アクションは失敗します。

たとえば、foo をローカルでビルドするよう Bazel がステートフル コンパイラに指示した場合、コンパイラは foo のビルド出力への参照を保持します。次に、Bazel がコンパイラ呼び出しに BUILD ファイルに依存関係を明示的に指定せずに foo に依存する bar をビルドするよう指示すると、同じコンパイラ インスタンスが両方のアクションに対して実行されている限り、アクションは正常に実行されます(ローカル実行の場合は一般的です)。ただし、リモート実行のシナリオでは、各ビルド アクションが個別のコンパイラ インスタンスを実行するため、コンパイラの状態と barfoo への暗黙的な依存関係が失われ、ビルドは失敗します。

こうした依存関係の問題を検出して排除できるように、Bazel 0.14.1 ではローカルの Docker サンドボックスを提供しています。このサンドボックスには、リモート実行と同じ依存関係に関する制限があります。サンドボックスを使用して、依存関係に関連するビルドエラーを特定して解決し、リモート実行用にビルドを準備します。詳細については、Docker サンドボックスを使用した Bazel リモート実行のトラブルシューティングをご覧ください。

プラットフォーム依存バイナリの管理

通常、ホスト プラットフォーム上にビルドされたバイナリは、依存関係が一致しない可能性があるため、任意のリモート実行プラットフォームでは安全に実行できません。たとえば、Bazel に付属の SingleJar バイナリはホスト プラットフォームをターゲットにしています。 ただし、リモート実行の場合は、リモート実行プラットフォームをターゲットとするように、コードのビルドプロセスの一環として SingleJar をコンパイルする必要があります。(ターゲット選択ロジックをご覧ください)。

実行プラットフォームで安全に実行できることが確実な場合を除き、ビルドに必要なビルドツールのバイナリをソースコードと一緒に配布しないでください。代わりに、次のいずれかを行います。

  • リモート実行プラットフォーム用にビルドできるように、ツールのソースコードを送信するか、外部から参照します。

  • 安定性が十分であれば、リモート実行環境(ツールチェーン コンテナなど)にこのツールをプリインストールし、ツールチェーン ルールを使用してビルドで実行します。

構成スタイルの WORKSPACE ルールの管理

Bazel の WORKSPACE ルールは、ビルドに必要なツールとライブラリのホスト プラットフォームをプローブするために使用できます。ローカルビルドの場合、これは Bazel の実行プラットフォームでもあります。ビルドがローカルのビルドツールとアーティファクトに明示的に依存している場合、リモート実行プラットフォームがホスト プラットフォームと同一でなければ、リモート実行時にビルドが失敗します。

WORKSPACE ルールによって実行される次の操作は、リモート実行に対応していません。

  • バイナリをビルドする。WORKSPACE ルールでコンパイル アクションを実行すると、ホスト プラットフォームと異なる場合、リモート実行プラットフォームと互換性のないバイナリが生成されます。

  • pip パッケージをインストールする。WORKSPACE ルールを介してインストールされる pip パッケージでは、その依存関係をホスト プラットフォームにプリインストールする必要があります。ホスト プラットフォーム専用に構築されたこのようなパッケージは、ホスト プラットフォームと異なる場合、リモート実行プラットフォームと互換性がありません。

  • ローカルツールやアーティファクトへのシンボリック リンク。WORKSPACE ルールで作成されたホスト プラットフォームにインストールされているツールまたはライブラリへのシンボリック リンクを使用すると、Bazel がそれらを見つけられないため、リモート実行プラットフォームでビルドが失敗します。代わりに、標準のビルド アクションを使用してシンボリック リンクを作成し、シンボリック リンクされたツールとライブラリに Bazel の runfiles ツリーからアクセスできるようにします。外部リポジトリ ディレクトリの外部でターゲット ファイルのシンボリック リンクに repository_ctx.symlink を使用しないでください。

  • ホスト プラットフォームの変更。リモート実行プラットフォームで予期しない動作が発生する可能性があるため、Bazel runfiles ツリーの外部でファイルを作成することや、環境変数を作成するなどの操作は行わないでください。

密閉型でない可能性のある動作を特定するには、Workspace ルールログを使用します。

外部依存関係がホスト プラットフォームに依存して特定のオペレーションを実行する場合、それらのオペレーションを次のように WORKSPACE とビルドルールに分割する必要があります。

  • プラットフォームの検査と依存関係の列挙。これらのオペレーションは、WORKSPACE ルールにより安全にローカルに実行できます。ルールにより、インストールされているライブラリを確認し、ビルドする必要があるパッケージをダウンロードして、コンパイルに必要なアーティファクトを準備できます。リモート実行の場合、これらのルールは、事前にチェックされたアーティファクトを使用して、ホスト プラットフォームの検査中に通常取得される情報を提供することもサポートする必要があります。事前にチェックされたアーティファクトにより、Bazel はローカルにあるかのように依存関係を記述できます。そのためには、条件ステートメントまたは --override_repository フラグを使用します。

  • ターゲット固有のアーティファクトとプラットフォームのミューテーションの生成またはコンパイル。これらのオペレーションは、通常のビルドルールを使用して実行する必要があります。外部依存関係のターゲット固有のアーティファクトを生成するアクションは、ビルド時に実行する必要があります。

リモート実行用の事前にチェックされたアーティファクトを簡単に生成するには、WORKSPACE ルールを使用して、生成されたファイルを出力します。これらのルールは、各ツールチェーン コンテナ内など、新しい実行環境ごとに実行し、リモート実行ビルドの出力をソース リポジトリに確認して、参照できます。

たとえば、TensorFlow の cudapython のルールの場合、WORKSPACE ルールは次の BUILD files を生成します。ローカル実行の場合、ホスト環境の確認によって生成されたファイルが使用されます。リモート実行の場合、環境変数の条件ステートメントにより、ルールでリポジトリにチェックインされたファイルを使用できます。

BUILD ファイルは、ローカルとリモートの両方で実行できる genrules を宣言し、以前に repository_ctx.symlink を介して実行されていた必要な処理を実行します(こちらを参照)。