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

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
問題を報告 ソースを表示

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

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

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

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

概要

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

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

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

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

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

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

ScalaRustGo に関する Bazel のビルドとテストのルールを対象としたツールチェーン ルールが現在存在しており、その他の言語やツール(bash など)用の新しいツールチェーン ルールが準備中です。そのルールで使用しているツールのツールチェーン ルールが存在しない場合は、ツールチェーン ルールの作成を検討してください。

暗黙的依存関係の管理

ビルドツールがビルド アクション間の依存関係にアクセスできる場合、リモート ビルド アクションはリモート アクションの別で実行されるため、これらのアクションはリモートで実行されると失敗します。一部のビルドツールは、ビルド アクション間で状態を保持し、ツール呼び出しに明示的に含まれていない依存関係にアクセスします。これにより、リモートで実行されるビルド アクションが失敗する可能性があります。

たとえば、Bazel はステートフル コンパイラに foo をローカルでビルドするように指示する場合、foo のビルド出力への参照を保持します。Bazel は、foo に依存する bar をビルドするようコンパイラに指示します。コンパイラ呼び出しに含めるために BUILD ファイルでその依存関係を明示せずに、両方のコンパイラに対して同じコンパイラ インスタンスが実行されている限り、このアクションは正常に実行されます(ローカル実行では一般的です)。ただし、リモート実行のシナリオでは、各ビルド アクションが個別のコンパイラ インスタンスを実行するため、コンパイラの状態と 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 ルールを使用して、生成されたファイルを出力します。これらのルールは、各ツールチェーン コンテナ内など、新しい実行環境ごとに実行し、参照先のソース リポジトリにリモート実行ビルドの出力を確認できます。

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

BUILD ファイルは、ローカルとリモートの両方で実行可能な genrules を宣言し、ここに示すように、以前は repository_ctx.symlink を使用して必要だった処理を実行します。