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

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

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

このページでは、さまざまな環境タイプまたは プラットフォームを参照する場合、次の用語を使用します。

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

概要

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

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

  • 多様な実行環境。ローカルビルド構成は、リモート実行環境に適しているとは限りません。

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

ツールチェーン ルールを使用したビルドツールの呼び出し

Bazel ツールチェーン ルールは、ビルドルールに、コンパイラやリンカーなどのビルドツールを使用するよう指示し、ルールの作成者が定義したパラメータを使用して構成する方法を指示する構成プロバイダです。ツールチェーン ルールを使用すると、ビルドルールとテストルールは、リモート実行と互換性のある予測可能な事前構成済みの方法でビルドツールを呼び出すことができます。たとえば、リモート実行環境で同等の値に設定されていない(またはまったく設定されていない)可能性がある PATHJAVA_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 の cudapython のルールの場合、WORKSPACE ルールは次の BUILD files を生成します。 ローカル実行では、ホスト環境のチェックによって生成されたファイルが使用されます。 リモート実行の場合、条件ステートメント 環境変数の により、ルールはリポジトリにチェックインされたファイルを使用できます。

BUILD ファイルは、ローカルとリモートの両方で実行できる genrules を宣言し、以前は repository_ctx.symlink を介して行われていた必要な処理 を、次に示すように実行します。