このページは、リモート実行に関する Bazel ルールの要件を理解し、カスタムビルドとテストルールを作成する Bazel ユーザーを対象としています。
リモート実行を使用すると、Bazel はデータセンターなどの別のプラットフォームでアクションを実行できます。Bazel は、リモート実行に gRPC プロトコルを使用します。分散リモート実行プラットフォームの提供を目的としたオープンソース プロジェクトである bazel-buildfarm を使用して、リモート実行を試すことができます。
このページでは、さまざまな環境タイプやプラットフォームを指す用語を使用します。
- ホスト プラットフォーム - Bazel が実行される場所。
- 実行プラットフォーム - Bazel アクションが実行されます。
- ターゲット プラットフォーム - ビルド出力(および一部のアクション)が実行される場所。
概要
リモート実行用に Bazel ビルドを構成する場合は、このページで説明するガイドラインに従って、リモートからエラーなしでビルドを実行できるようにする必要があります。これは、リモート実行の性質によります。
分離されたビルド アクション。ビルドツールは状態を保持せず、ツール間で依存関係がリークすることはありません。
多様な実行環境。ローカルビルド構成は、必ずしもリモート実行環境に適しているわけではありません。
このページでは、リモート実行用の Bazel カスタム ビルドとテストルールの実装時に発生する可能性のある問題と、その回避方法について説明します。取り上げるトピックは次のとおりです。
ツールチェーン ルールによるビルドツールの呼び出し
Bazel ツールチェーン ルールは、使用するビルドツール(コンパイラやリンカーなど)と、ルールの作成者が定義したパラメータを使用してツールを構成する方法をビルドルールに指示する構成プロバイダです。ツールチェーン ルールを使用すると、ビルドルールとテストルールから、リモート実行と互換性のある、予測可能な事前構成された方法でビルドツールを呼び出すことができます。たとえば、PATH
、JAVA_HOME
、またはリモート実行環境で同等の値に設定されていない(またはまったく)設定されていない可能性のある他のローカル変数を介してビルドツールを呼び出すのではなく、ツールチェーン ルールを使用します。
現在、Scala、Rust、Go の Bazel ビルドおよびテストルールに関するツールチェーン ルールが存在し、他の言語やツール(bash など)向けの新しいツールチェーン ルールが進行中です。 ルールで使用するツールにツールチェーン ルールが存在しない場合は、ツールチェーン ルールの作成を検討してください。
暗黙的な依存関係の管理
ビルドツールがビルド アクション間の依存関係にアクセスできる場合、各リモートビルド アクションは互いに独立して実行されるため、リモート実行時にこれらのアクションは失敗します。一部のビルドツールは、ツール呼び出しに明示的に含まれていないビルド アクションやアクセスの依存関係全体で状態を保持します。その場合、リモートで実行されたビルド アクションは失敗します。
たとえば、foo をローカルでビルドするよう Bazel がステートフル コンパイラに指示した場合、コンパイラは foo のビルド出力への参照を保持します。次に、Bazel がコンパイラ呼び出しに BUILD ファイルに依存関係を明示的に指定せずに foo に依存する bar をビルドするよう指示すると、同じコンパイラ インスタンスが両方のアクションに対して実行されている限り、アクションは正常に実行されます(ローカル実行の場合は一般的です)。ただし、リモート実行のシナリオでは、各ビルド アクションが個別のコンパイラ インスタンスを実行するため、コンパイラの状態と bar の foo への暗黙的な依存関係が失われ、ビルドは失敗します。
こうした依存関係の問題を検出して排除できるように、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 の cuda
と python
のルールの場合、WORKSPACE
ルールは次の BUILD files
を生成します。ローカル実行の場合、ホスト環境の確認によって生成されたファイルが使用されます。リモート実行の場合、環境変数の条件ステートメントにより、ルールでリポジトリにチェックインされたファイルを使用できます。
BUILD
ファイルは、ローカルとリモートの両方で実行できる genrules
を宣言し、以前に repository_ctx.symlink
を介して実行されていた必要な処理を実行します(こちらを参照)。