このページは、カスタムのビルドルールとテストルールを作成する Bazel ユーザーを対象としています。 リモート実行のコンテキストで Bazel ルールの要件を理解したいユーザー向けです。
リモート実行を使用すると、Bazel はデータセンターなどの別のプラットフォームでアクションを実行できます。Bazel は、リモート実行に gRPC プロトコル を使用します。リモート実行は、分散リモート実行プラットフォームの提供を目的としたオープンソース プロジェクトである bazel-buildfarmで試すことができます。
このページでは、さまざまな環境タイプまたは プラットフォームを参照するときに、次の用語を使用します。
- ホスト プラットフォーム - Bazel が実行される場所。
- 実行プラットフォーム \- Bazel アクションが実行される場所。
- ターゲット プラットフォーム \- ビルド出力(および一部のアクション)が実行される場所。
概要
リモート実行用に Bazel ビルドを構成する場合は、このページで説明する ガイドラインに沿って、ビルドがリモートで エラーなく実行されるようにする必要があります。これは、リモート実行の特性によるものです。
ビルド アクションの分離。ビルドツールは状態を保持せず、依存関係が漏洩することはありません。
多様な実行環境。ローカルビルド構成は、リモート実行環境に適しているとは限りません。
このページでは、リモート実行用にカスタムの Bazel ビルドルールとテストルールを実装する際に発生する可能性のある問題と、その回避方法について説明します。次のトピックについて説明します。
ツールチェーン ルールを使用したビルドツールの呼び出し
Bazel ツールチェーン ルールは、ビルドルールに対して、
コンパイラやリンカーなどのビルドツールを使用するよう指示し、
ルールの作成者が定義したパラメータを使用して構成する方法を指示する構成プロバイダです。ツールチェーン ルールを使用すると、ビルド
とテストルールは、リモート実行と互換性のある予測可能な事前構成済みの方法
でビルドツールを呼び出すことができます。たとえば、リモート実行環境で同等の値に設定されていない(またはまったく設定されていない)可能性がある PATH、JAVA_HOME などのローカル
変数を使用してビルドツールを呼び出すのではなく、ツールチェーン ルール
を使用します。
Scalaルールで使用するツールにツールチェーン ルールが存在しない場合は、 ツールチェーン ルールの作成を検討してください。
暗黙的な依存関係の管理
ビルドツールがビルド アクション間で依存関係にアクセスできる場合、各リモートビルド アクションは他のアクションとは別に実行されるため、リモートで実行するとアクションは 失敗します。一部のビルドツールは、ビルド アクション間で状態を保持し、 ツールの 呼び出しに明示的に含まれていない依存関係にアクセスします。これにより、リモートで実行されたビルド アクションが失敗します。
たとえば、Bazel がステートフル コンパイラに foo をローカルでビルドするように指示すると、 コンパイラは foo のビルド出力への参照を保持します。次に、Bazel がコンパイラに foo に依存する bar をビルドするように指示し、コンパイラの呼び出しに含めるために BUILD ファイルでその依存関係を明示的に指定しない場合、同じコンパイラ インスタンスが両方のアクションで実行される限り(ローカル実行の場合と同様)、アクションは正常に実行されます。ただし、リモート実行シナリオでは、各ビルド アクションが個別のコンパイラ インスタンスを実行するため、コンパイラの状態と bar の foo に対する暗黙的な依存関係が失われ、ビルドは失敗します。
これらの依存関係の問題を検出して解消するために、Bazel 0.14.1 では ローカル Docker サンドボックスが提供されています。このサンドボックスには、リモート 実行と同じ依存関係の制限があります。サンドボックスを使用して、依存関係に関連するビルドエラーを特定して解決し、リモート実行用にビルドを準備します。 詳細については、Docker サンドボックスを使用した Bazel リモート実行のトラブルシューティング をご覧ください。
プラットフォーム依存のバイナリの管理
通常、ホスト プラットフォームでビルドされたバイナリは、依存関係が一致しない可能性があるため、任意のリモート実行プラットフォームで安全に実行できません。たとえば、Bazel に付属の SingleJar バイナリはホスト プラットフォームをターゲットにしています。 ただし、リモート実行の場合、SingleJar はコードのビルド プロセス の一部としてコンパイルして、リモート実行プラットフォームをターゲットにする必要があります( ターゲット選択ロジックをご覧ください)。
実行プラットフォームで安全に実行できることが確実でない限り、ビルドに必要なビルドツールのバイナリをソースコードとともに配布しないでください。 代わりに、 次のいずれかを行います。
ツール用のソースコードを配布するか、外部から参照して、リモート実行プラットフォーム用に ビルドできるようにします。
ツールが十分に安定している場合は、リモート実行環境( ツールチェーン コンテナなど)に事前にインストールし、ツールチェーン ルールを使用してビルドで実行します。
構成スタイルの WORKSPACE ルールの管理
Bazel の WORKSPACE ルールを使用して、ビルドに必要なツール
とライブラリのホスト プラットフォームをプローブできます。ローカルビルドの場合、これは Bazel の
実行プラットフォームでもあります。ビルドがローカルビルドツールと
アーティファクトに明示的に依存している場合、リモート実行プラットフォーム
がホスト プラットフォームと同一でないと、リモート実行中に失敗します。
WORKSPACE ルールによって実行される次のアクションは、
リモート実行と互換性がありません。
バイナリのビルド。
WORKSPACEルールでコンパイル アクションを実行すると、ホスト プラットフォームと異なるリモート実行プラットフォームと互換性のないバイナリが生成されます。pipパッケージのインストール。pipパッケージをWORKSPACEルールを使用してインストールするには、依存関係がホスト プラットフォームに事前にインストールされている必要があります。 ホスト プラットフォーム専用にビルドされたこのようなパッケージは、ホスト プラットフォームと異なるリモート実行プラットフォームと 互換性がありません。ローカルツールまたはアーティファクトへのシンボリック リンク。ツールまたはライブラリへのシンボリック リンク
WORKSPACEルールを使用して作成された、ホスト プラットフォームにインストールされているツールまたはライブラリへのシンボリック リンクは、Bazel がそれらを検出できないため、リモート実行プラットフォームでビルドが失敗します。代わりに、標準のビルド アクションを使用してシンボリック リンクを作成し、 シンボリック リンクされたツールとライブラリが Bazel のrunfilesツリーからアクセスできるようにします。repository_ctx.symlinkを使用して、外部リポジトリ ディレクトリ外のターゲット ファイルにシンボリック リンクしないでください。ホスト プラットフォームの変更。Bazel
runfilesツリー外にファイルを作成したり、環境変数を作成したりするなどのアクションは、 リモート実行プラットフォームで予期しない動作をする可能性があるため、避けてください。
非密閉型の動作の可能性を見つけるには、ワークスペース ルールのログを使用します。
外部依存関係がホスト
プラットフォームに依存する特定のオペレーションを実行する場合は、次のように WORKSPACE ルールとビルド
ルールの間でオペレーションを分割する必要があります。
プラットフォームの検査と依存関係の列挙。これらのオペレーションは
WORKSPACEルールを使用してローカルで安全に実行できます。これにより、インストールされている ライブラリを確認し、ビルドする必要があるパッケージをダウンロードして、コンパイルに必要な アーティファクトを準備できます。リモート実行の場合、これらのルールでは 事前に確認されたアーティファクトを使用して、通常はホスト プラットフォームの検査中に取得される情報を提供する必要があります。事前に確認された アーティファクトを使用すると、Bazel は依存関係をローカルであるかのように記述できます。これには、 条件ステートメントまたは--override_repositoryフラグを使用します。ターゲット固有のアーティファクトとプラットフォームの変更の生成またはコンパイル。 これらのオペレーションは、通常のビルドルールを使用して実行する必要があります。外部依存関係のターゲット固有のアーティファクトを生成するアクションは、ビルド中に実行する必要があります。
リモート実行用に事前に確認されたアーティファクトを簡単に生成するには、
WORKSPACE ルールを使用して生成されたファイルを出力します。これらのルールは、各ツールチェーン コンテナ内など、新しい
実行環境ごとに実行し、リモート実行ビルドの
出力をソース リポジトリにチェックインして参照できます。
たとえば、Tensorflow の cuda
と python のルールの場合、WORKSPACE ルールは次の BUILD files を生成します。
ローカル実行では、ホスト環境の確認によって生成されたファイルが使用されます。
リモート実行の場合、条件ステートメント
環境変数の
により、ルールはリポジトリにチェックインされたファイルを使用できます。
BUILD ファイルは、ローカルとリモートの両方で実行できる genrules
を宣言し、以前は repository_ctx.symlink を介して行われていた必要な処理
を、ここで示すように実行します。