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

問題を報告する ソースを表示

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

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

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

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

概要

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

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

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

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

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

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

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

暗黙的な依存関係の管理

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

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

これらの依存関係の問題を検出して除去できるように、Bazel 0.14.1 にはローカル Docker サンドボックスが用意されています。この依存関係には、リモート実行と同じ制約があります。サンドボックスを使用し、依存関係関連のビルドエラーを特定して解決し、リモート実行でビルドを準備します。詳細については、Docker Sandbox を使用した 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 で実行されていた処理を実行します。