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

問題を報告する ソースを表示 ナイトリー · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

概要

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

  • 分離されたビルド アクション。ビルドツールは状態を保持しないため、ビルドツール間で依存関係が漏洩することはありません。

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

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

ツールチェーン ルールによるビルドツールの呼び出し

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

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

暗黙的な依存関係の管理

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

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

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

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