このページでは、Bazel を繰り返し実行するときに Bazel のビルド パフォーマンスを最適化する方法について説明します。
Bazel のランタイム状態
Bazel の呼び出しには、相互作用する複数の部分が関与します。
bazel
コマンドライン インターフェース(CLI)は、ユーザー向けのフロントエンド ツールであり、ユーザーからコマンドを受け取ります。CLI ツールは、個別の出力ベースごとに Bazel サーバーを起動します。Bazel サーバーは通常は永続的ですが、リソースを浪費しないように、アイドル状態が続くとシャットダウンします。
Bazel サーバーは、特定のコマンド(
build
、run
、cquery
など)の読み込みと分析ステップを実行します。このとき、ビルドグラフの必要な部分がメモリ内に構築されます。生成されたデータ構造は、分析キャッシュの一部として Bazel サーバーに保持されます。Bazel サーバーはアクションの実行も実行できます。また、リモート実行するように設定されている場合は、アクションを送信してリモートで実行することもできます。アクションの実行結果もキャッシュに保存されます。つまり、アクション キャッシュ(または実行キャッシュ)に保存されます。これはローカルまたはリモートであり、Bazel サーバーで共有できます。
Bazel 呼び出しの結果は、出力ツリーで使用できます。
Bazel を反復的に実行する
一般的なデベロッパー ワークフローで、コードを繰り返しビルド(または実行)することはよくあります(コンパイル エラーを解決したり、失敗したテストを調査したりする場合など)。このような状況では、bazel
の繰り返し呼び出しで、基盤となる繰り返しアクション(コンパイラの呼び出しやテストの実行など)に比べてオーバーヘッドが最小限に抑えられることが重要です。
これを念頭に置いて、Bazel のランタイム状態をもう一度見てみましょう。
分析キャッシュは重要なデータです。コールド実行(Bazel サーバーの起動直後や分析キャッシュが破棄されたときの実行)の読み込みフェーズと分析フェーズだけで、かなりの時間が費やされる可能性があります。1 回のコールドビルドが成功した場合(本番環境リリースの場合など)は、この費用は許容できますが、同じターゲットを繰り返しビルドする場合は、この費用を償却し、呼び出しごとに繰り返さないことが重要です。
分析キャッシュは比較的不安定です。まず、これは Bazel サーバーの処理中状態の一部であるため、サーバーが失われるとキャッシュも失われます。ただし、キャッシュは非常に簡単に無効になります。たとえば、多くの bazel
コマンドライン フラグによってキャッシュが破棄されます。これは、多くのフラグがビルドグラフに影響するためです(構成可能な属性が原因など)。一部のフラグの変更によって、Bazel サーバーが再起動されることもあります(起動オプションの変更など)。
適切な実行キャッシュは、ビルドのパフォーマンスにも役立ちます。実行キャッシュは、ローカルのディスクまたはリモートに保存できます。キャッシュは Bazel サーバー間で、またデベロッパー間で共有できます。
分析キャッシュを破棄しないようにする
分析キャッシュが破棄されたか、サーバーが再起動された場合、Bazel は警告を出力します。反復使用中は、次のいずれかを行うことは避けてください。
反復的なワークフローの途中で
bazel
フラグを変更する際は注意してください。たとえば、bazel build -c opt
とbazel cquery
を混在させると、各コマンドで他方の分析キャッシュが破棄されます。一般に、特定のワークフローの期間中は、固定されたフラグのセットを使用することをおすすめします。Bazel サーバーが失われると、分析キャッシュも失われます。Bazel サーバーは、構成可能なアイドル時間を経過するとシャットダウンします。この時間は、bazelrc ファイルでニーズに合わせて構成できます。また、起動フラグが変更されるとサーバーが再起動されるため、可能な限りフラグの変更は避けてください。
Bazel の実行中に Ctrl-C キーを繰り返し押すと、Bazel サーバーが強制終了します。注意してください。不要になった実行中のビルドを中断して時間を節約しようとするかもしれませんが、Ctrl-C を 1 回押すだけで、現在の呼び出しを正常に終了できます。
同じワークスペースから複数のフラグセットを使用する場合は、
--output_base
フラグで切り替えて、複数の異なる出力ベースを使用できます。各出力ベースには独自の Bazel サーバーが割り当てられます。