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