Bazel を使用してプログラムをビルドする

問題を報告 ソースを表示 Nightly · 7.4 . 7.3 7.2 7.1 7.0 6.5

このページでは、Bazel を使用したプログラムのビルド方法、ビルドコマンドの構文、 ターゲット パターンの構文。

クイックスタート

Bazel を実行するには、ベース workspace ディレクトリに移動します。 または「bazel」と入力します。新しいワークスペースを作成する必要がある場合は、build をご覧ください。

bazel help
                             [Bazel release bazel version]
Usage: bazel command options ...

使用できるコマンド

  • analyze-profile: ビルド プロファイル データを分析します。
  • aquery: 分析後アクション グラフでクエリを実行します。
  • build: 指定したターゲットをビルドします。
  • canonicalize-flags: Bazel フラグを正規化します。
  • clean: 出力ファイルを削除し、必要に応じてサーバーを停止します。
  • cquery: 分析後の依存関係グラフ クエリを実行します。
  • dump: Bazel サーバー プロセスの内部状態をダンプします。
  • help: コマンドまたはインデックスのヘルプを出力します。
  • info: bazel サーバーに関するランタイム情報を表示します。
  • fetch: ターゲットのすべての外部依存関係を取得します。
  • mobile-install: モバイル デバイスにアプリをインストールします。
  • query: 依存関係グラフのクエリを実行します。
  • run: 指定されたターゲットを実行します。
  • shutdown: Bazel サーバーを停止します。
  • test: 指定されたテスト ターゲットをビルドして実行します。
  • version: Bazel のバージョン情報を出力します。

困ったときは

  • bazel help command: command のヘルプとオプションを出力します。
  • bazel helpstartup_options: Bazel をホストする JVM のオプション。
  • bazel helptarget-syntax: ターゲットを指定するための構文について説明します。
  • bazel help info-keys: info コマンドによって使用されるキーのリストを表示します。

bazel ツールは、コマンドと呼ばれる多くの機能を実行します。最もよく使用されるのは bazel buildbazel test です。bazel help を使用してオンライン ヘルプ メッセージを参照できます。

1 つのターゲットをビルドする

ビルドを開始する前に、ワークスペースが必要です。ワークスペースは、アプリケーションのビルドに必要なすべてのソースファイルを含むディレクトリ ツリーです。Bazel では、完全に読み取り専用ボリュームからビルドを実行できます。

Bazel でプログラムをビルドするには、bazel build と続けてビルドするターゲットを入力します。

bazel build //foo

//foo をビルドするコマンドを実行すると、次のような出力が表示されます。

INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions

まず、Bazel はターゲットの依存関係グラフ内のすべてのパッケージを読み込みます。この 宣言された依存関係、ターゲットの BUILD に直接リストされているファイルを含む 、一時的な依存関係(アプリケーションの BUILD ファイルにリストされているファイル)を 依存関係が存在します。すべての依存関係を特定した後、Bazel は依存関係の正確性を分析し、ビルド アクションを作成します。最後に、Bazel の実行を行います。 ビルドのコンパイルやその他のツールが含まれます。

ビルドの実行フェーズで、Bazel は進行状況メッセージを出力します。進捗状況 現在のビルドステップ(コンパイラ、リンカーなど)がそのまま ビルド アクションの合計数に対する完了した数を示します。「 ビルドが開始されると、多くの場合、Bazel が検出するにつれて合計アクション数が増加します 数値は数秒以内に安定します。

ビルドの最後に、Bazel は、リクエストされたターゲットを 正しくビルドされていないか、正しい場合は、出力ファイルを できます。ビルドを実行するスクリプトは、この出力を確実に解析できます。 --show_result

同じコマンドをもう一度入力すると、ビルドが大幅に速く終了します。

bazel build //foo
INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 0.144s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action

これは null ビルドです。変更されていないため、再読み込みするパッケージも、実行するビルドステップもありません。「foo」またはその依存関係が変更された場合、Bazel は一部のバイルアクションを再実行するか、増分ビルドを完了します。

複数のターゲットのビルド

Bazel では、ビルドするターゲットをさまざまな方法で指定できます。これらを総称してターゲット パターンと呼びます。この構文は、buildtestquery などのコマンドで使用されます。

ラベルは、BUILD ファイルで依存関係を宣言する場合など、個々のターゲットを指定するために使用されますが、Bazel のターゲット パターンは複数のターゲットを指定します。ターゲット パターンは、トレーニング データの ワイルドカードを使用して、ターゲットのセットのラベル構文。最も単純なケースでは 有効なラベルも有効なターゲット パターンで、 あります。

// で始まるターゲット パターンはすべて、現在のワークスペースを基準に解決されます。

//foo/bar:wiz 単一のターゲット //foo/bar:wiz のみ。
//foo/bar //foo/bar:bar と同じです。
//foo/bar:all パッケージ foo/bar 内のすべてのルール ターゲット。
//foo/... ディレクトリ foo の下のすべてのパッケージ内のすべてのルール ターゲット。
//foo/...:all ディレクトリ foo の下にあるすべてのパッケージ内のすべてのルール ターゲット。
//foo/...:* foo ディレクトリの下にあるすべてのパッケージ内のすべてのターゲット(ルールとファイル)。
//foo/...:all-targets ディレクトリ foo の下のすべてのパッケージ内のすべてのターゲット(ルールとファイル)。
//... ワークスペース内のパッケージ内のすべてのターゲット。これにはターゲットは含まれません。 外部リポジトリから。
//:all トップレベル パッケージ内のすべてのターゲット( アクセスできます。

// で始まらないターゲット パターンは、現在の作業ディレクトリを基準に解決されます。以下の例では、foo の作業ディレクトリを想定しています。

:foo //foo:foo に相当します。
bar:wiz //foo/bar:wiz と同じです。
bar/wiz 次と同等です。
  • //foo/bar/wiz:wizfoo/bar/wiz がパッケージの場合)
  • //foo/bar:wizfoo/bar がパッケージの場合)
  • それ以外の場合は //foo:bar/wiz
bar:all //foo/bar:all に相当します。
:all //foo:all に相当します。
...:all //foo/...:all に相当します。
... //foo/...:all に相当します。
bar/...:all //foo/bar/...:all に相当します。

デフォルトでは、再帰ターゲット パターンのディレクトリ シンボリック リンクに従いますが、 出力ベースの下にポイントするものは除きます。 ワークスペースのルート ディレクトリに作成されるシンボリック リンク。

また、Bazel は、次のような名前のファイルを含むディレクトリで再帰ターゲット パターンを評価するときに、シンボリック リンクをたどりません。DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN

foo/...パッケージのワイルドカードで、ディレクトリ foo の下にあるすべてのパッケージを再帰的に指定します(パッケージパスのすべてのルートについて)。:allターゲットに対するワイルドカードで、パッケージ内のすべてのルールに一致します。この 2 つは foo/...:all のように組み合わせることができます。両方のワイルドカードを使用する場合は、foo/... と省略できます。

:*(または :all-targets)は、すべてのターゲットに一致するワイルドカードです。 (通常はルールによってビルドされないファイルを含む)が、一致するパッケージに java_binary ルールに関連付けられた _deploy.jar ファイルなど。

これは、:*:allスーパーセットを示すことを意味します。潜在的に 混乱を招くため、この構文ではおなじみの :all ワイルドカードを _deploy.jar などのビルド ターゲットは望ましくない一般的なビルド。

さらに、Bazel では、 ラベル構文。これは、多くの場合、Bash ファイル名の展開を使用するときに便利です。 たとえば、foo/bar/wiz//foo/bar:wiz と同等です( パッケージ foo/bar)または //foo:bar/wiz(パッケージ foo がある場合)に移動します。

多くの Bazel コマンドは、ターゲット パターンのリストを引数として受け入れます。これらのコマンドはすべて、接頭辞否定演算子 - を尊重します。これは、前の引数で指定されたセットからターゲットのセットを減算するために使用できます。順序が重要であることに注意してください。次に例を示します。

bazel build foo/... bar/...

は「foo の下のすべてのターゲットと bar の下のすべてのターゲットをビルド」を意味します。

bazel build -- foo/... -foo/bar/...

は、「foo/bar の下にあるターゲットを除く foo の下のすべてのターゲットをビルドする」ことを意味します。- で始まる後続の引数が追加オプションとして解釈されないようにするには、-- 引数が必要です。

ただし、この方法で目標値を引き算しても、 ターゲットの依存関係の可能性があるため、ビルドされないことを保証する 減らされなかった割合ですたとえば、ターゲット //foo:all-apis があるとします。 //foo/bar:api に依存する場合、後者は次のようにビルドされます。 構築の一部になります

tags = ["manual"] を含むターゲットは、bazel buildbazel test などのコマンドで指定した場合、ワイルドカード ターゲット パターン(...:*:all など)に含まれません(ただし、負のワイルドカード ターゲット パターンには含まれます。つまり、減算されます)。すべきこと コマンドラインで明示的なターゲット パターンを使用して、 Bazel でビルド/テストしたい場合に使用します。一方、bazel query は実行されません。 フィルタリングが自動的に行われ、 bazel query)。

外部依存関係の取得

デフォルトでは、Bazel はビルド中に外部依存関係をダウンロードしてシンボリック リンクを作成します。しかし、これは望ましくない場合があります。たとえば、 新しい外部依存関係が追加された場合や、必要に応じて構成を 「プリフェッチ」(フライト前など、オフラインになる前など)に行うことをおすすめします。ビルド中に新しい依存関係が追加されないようにするには、--fetch=false フラグを指定します。このフラグは リポジトリ ルールのうち、ローカル ディレクトリのディレクトリを 表示されます。local_repository への変更など。 new_local_repository と Android SDK および NDK リポジトリ ルール 値は --fetch の値に関係なく常に有効になります。

ビルド中にフェッチを禁止し、Bazel が新しい外部依存関係を見つけると、ビルドは失敗します。

bazel fetch を実行すると、依存関係を手動で取得できます。条件 ビルド中に許可しない場合は、bazel fetch を実行する必要があります。

  • 初めてビルドする前に。
  • 新しい外部依存関係を追加した後。

一度実行すると、WORKSPACE 関数が実行されるまで再度実行する必要はありません。 おすすめします。

fetch は、依存関係を取得するターゲットのリストを取ります。対象 たとえば、//foo:bar のビルドに必要な依存関係を取得します。 および //bar:baz:

bazel fetch //foo:bar //bar:baz

ワークスペースのすべての外部依存関係を取得するには、次のコマンドを実行します。

bazel fetch //...

使用しているすべてのツール(ライブラリ JAR から JDK 自体まで)がワークスペースのルートにある場合は、bazel fetch を実行する必要はありません。ただし、ワークスペース ディレクトリの外部で何かを使用している場合、Bazel は bazel build の実行前に bazel fetch を自動的に実行します。

リポジトリ キャッシュ

Bazel は、同じファイルであっても、同じファイルを複数回取得することを回避しようとします。 別のワークスペースでファイルが必要な場合や、外部 IP アドレスの定義が リポジトリが変更されましたが、同じファイルをダウンロードする必要があります。これを行うために、bazel はダウンロードしたすべてのファイルをリポジトリ キャッシュにキャッシュに保存します。デフォルトでは、このキャッシュは ~/.cache/bazel/_bazel_$USER/cache/repos/v1/ にあります。ロケーションは --repository_cache オプションで変更できます。「 キャッシュは、すべてのワークスペースとインストールされている bazel のバージョンで共有されます。 次の場合、エントリはキャッシュから取得されます。 Bazel は正しいファイルのコピーがあることを確実に認識しています。つまり、 ダウンロード リクエストに、指定されたファイルとそれを含むファイルの SHA256 サムが キャッシュにあります。そのため、各外部ファイルのハッシュを指定することは、 セキュリティの観点から優れたアイデアを得られるだけでなく、また、 ダウンロードしないようにできます。

キャッシュ ヒットごとに、キャッシュ内のファイルの変更時間が更新されます。これにより、キャッシュ ディレクトリ内のファイルが最後に使用された際に、 キャッシュを手動でクリーンアップするなど 選択できますキャッシュには、アップストリームで利用できなくなったファイルのコピーが含まれている可能性があるため、キャッシュは自動的にクリーンアップされません。

ディストリビューション ファイル ディレクトリ

ディストリビューション ディレクトリも、不要な Bazel を回避するメカニズムの一つです。 ダウンロードされます。Bazel は、リポジトリ キャッシュの前にディストリビューション ディレクトリを検索します。 主な違いは配布ディレクトリには手動の 学習しました。

--distdir=/path/to-directory オプションを使用すると、読み取り専用のディレクトリを追加して、ファイルを取得するのではなく検索できます。そのようなディレクトリからファイル名が は URL のベース名と同じで、さらにファイルのハッシュが ダウンロード リクエストで指定された値と同じである必要があります。この方法は、 ファイル ハッシュは WORKSPACE 宣言で指定されます。

ファイル名の条件は正確性のために必要ありませんが、指定したディレクトリごとに候補ファイルの数を 1 つに減らすことができます。この方法では、そのようなディレクトリ内のファイル数が大きくなっても、ディストリビューション ファイル ディレクトリの指定は効率的です。

エアギャップのある環境での Bazel の実行

Bazel のバイナリサイズを小さく保つため、Bazel の暗黙的な依存関係は、初めて実行するときにネットワーク経由で取得されます。これらの暗黙的な依存関係は、 すべての人にとって必要ではない可能性があるツールチェーンやルールが含まれています。たとえば、Android ツールは、Android プロジェクトのビルド時にのみバンドル解除され、フェッチされます。

ただし、これらの暗黙的な依存関係は、WORKSPACE の依存関係をすべてベンダー化しても、エアギャップ環境で Bazel を実行するときに問題が発生する可能性があります。これを解決するには、配布ディレクトリを用意し、 ネットワーク アクセスを備えたマシン上にこれらの依存関係を格納し、 クローズド・アプローチでクローズドな環境に 移行する必要があるからです

ディストリビューション ディレクトリを準備するには、--distdir フラグを使用します。新しい Bazel バイナリ バージョンごとに、この操作を 1 回行う必要があります。なぜなら、 暗黙的な依存関係はリリースごとに異なる場合があります。

エアギャップのある環境の外でこれらの依存関係を構築するには、まず、 適切なバージョンの Bazel ソースツリーを確認します。

git clone https://github.com/bazelbuild/bazel "$BAZEL_DIR"
cd "$BAZEL_DIR"
git checkout "$BAZEL_VERSION"

次に、その特定の Bazel バージョンの暗黙的なランタイム依存関係を含む tarball をビルドします。

bazel build @additional_distfiles//:archives.tar

この tarball を、エアギャップ環境にコピーできるディレクトリにエクスポートします。--distdir はディレクトリのネストレベルで非常に繊細な動作になる可能性があるため、--strip-components フラグに注意してください。

tar xvf bazel-bin/external/additional_distfiles/archives.tar \
  -C "$NEW_DIRECTORY" --strip-components=3

最後に、エアギャップのある環境で Bazel を使用する場合は、--distdir フラグを指定します。便宜上、.bazelrc エントリとして追加することもできます。

build --distdir=path/to/directory

ビルド構成とクロスコンパイル

特定のビルドの動作と結果を指定するすべての入力は、 大きく 2 つに分類されます1 つ目の種類は、プロジェクトの BUILD ファイルに保存される固有の情報(ビルドルール、その属性の値、その推移的依存関係の完全なセット)です。2 つ目の種類は、ユーザーまたはユーザーから提供された外部データまたは環境データです。 ターゲット アーキテクチャ、コンパイル、リンクの選択 ツールチェーン構成オプションが含まれます。環境データの完全なセットを「構成」と呼びます。

1 つのビルドに複数の構成が存在する場合があります。検討すべき事項 クロスコンパイル(64 ビット用の //foo:bin 実行可能ファイルをビルドします) ワークステーションは 32 ビットマシンです。ビルドによって 64 ビットを作成できるツールチェーンを使用して //foo:bin をビルドする必要がある 実行時に使用するさまざまなツールをビルドシステムで構築する必要もあります。 たとえば、ソースからビルドされ、その後にツールが これらはワークステーションで実行するように構築する必要があります。したがって 2 つの構成を識別できます。exec 構成は、 ビルド中に実行するツールをビルドするためのターゲット構成リクエスト構成でもかまいませんが、「ターゲット構成」と呼ぶこともあります。 その単語にはすでに多くの意味がありますが)に基づき、 バイナリが分割されます。

通常、リクエストされたビルド ターゲット(//foo:bin)と 1 つ以上の実行ツール(一部のベース ライブラリなど)の両方の前提条件となるライブラリが多数あります。このようなライブラリは、実行構成用とターゲット構成用に 2 回ビルドする必要があります。Bazel がお客様のデータを 両方のバリアントがビルドされ、派生ファイルが保持されるようにします。 干渉を避けるために分離する。通常、このようなターゲットは同時にビルドできます。 これらは互いに独立しているからです特定のターゲットが 2 回ビルドされていることを示す進行状況メッセージが表示される場合、これが原因である可能性が高いです。

exec 構成は、次のようにターゲット構成から派生します。

  • --host_crosstool_top が指定されていない限り、リクエスト構成で指定されたバージョンの Crosstool(--crosstool_top)を使用します。
  • --cpu には --host_cpu の値を使用します(デフォルト: k8)。
  • リクエスト構成で指定されている --compiler--use_ijars と同じ値を使用します。--host_crosstool_top が使用されている場合、--host_cpu の値を使用して、exec 構成の Crosstool で default_toolchain を検索します(--compiler は無視されます)。
  • --javabase には --host_javabase の値を使用します。
  • --java_toolchain には --host_java_toolchain の値を使用します。
  • C++ コード用に最適化されたビルドを使用します(-c opt)。
  • デバッグ情報を生成しない(--copt=-g0)。
  • 実行可能ファイルと共有ライブラリからデバッグ情報を削除します(--strip=always)。
  • すべての派生ファイルを、可能なリクエスト構成で使用される場所とは異なる特別な場所に配置します。
  • ビルドデータでバイナリのスタンプを抑制します(--embed_* オプションを参照)。
  • その他の値はすべてデフォルトのままにします。

リクエスト構成から個別の実行構成を選択する理由はいくつかあります。最も重要な点は次のとおりです。

まず、ストリップされて最適化されたバイナリを使用することで、 ツールのリンクと実行、ツールが占有するディスク容量、 分散ビルドでのネットワーク I/O 時間。

次に、すべてのビルドで exec 構成と request 構成を分離することで、 環境に小さな変更を加えることによる高コストの 構成(リンカー オプションの変更など)は、 挙げられます

増分再ビルドを修正する

Bazel プロジェクトの主な目標の 1 つは、 構成されます。以前のビルドツール、特に Make をベースとしたビルドツールは、 思い込みが足りないと感じているかもしれません。

まず、ファイルのタイムスタンプは単調に増加します。これは一般的なケースですが、この前提に違反することは非常に簡単です。ファイルの以前のリビジョンと同期すると、そのファイルの変更時間が短縮され、Make ベースのシステムは再ビルドされません。

一般的に、Make はファイルの変更を検出しますが、変更を検出しません。 使用できます。特定のビルドでコンパイラに渡されるオプションを変更した場合 Make はコンパイラを再実行しないため、手動で破棄し、 make clean を使用した以前のビルドの無効な出力。

また Make は、いずれかの Pod の停止に失敗しても堅牢ではありません。 そのサブプロセスが出力ファイルへの書き込みを開始した後、しばらく 現在の Make の実行が失敗すると、後続の Make の呼び出しは、 むやみに切り捨てられた出力ファイルが有効であると仮定する( 再ビルドされることはありません。同様に Make プロセスが 同様の状況が発生する可能性があります。

Bazel では、このような前提条件は回避されています。Bazel は、以前に行われたすべての作業のデータベースを維持します。ビルドステップの入力ファイルのセット(およびそのタイムスタンプ)と、そのビルドステップのコンパイル コマンドがデータベース内の 1 つと完全に一致し、データベース エントリの出力ファイルのセット(およびそのタイムスタンプ)がディスク上のファイルのタイムスタンプと完全に一致する場合にのみ、ビルドステップを省略します。入力ファイルまたは出力ファイル、またはコマンド自体に変更を加えると、ビルドステップが再実行されます。

適切な増分ビルドを利用するユーザーにとってのメリットは、 混同です。(また、make clean の使用によって発生する再ビルドの待機時間(必要な場合、またはプリエンプティブの場合)が短縮されます)。

ビルドの整合性と増分ビルド

形式上、ビルドの状態は、想定するすべてのしきい値に 出力ファイルが存在し、その内容が手順または ルールを作成できます。ソースファイルを編集すると、 ビルドは「不整合」と見なされ、次回の実行まで一貫性がない状態を保ちます。 ビルドツールが正常に完了します。この状況を不安定 不整合。これはあくまで一時的なものであり、整合性は ビルドツールを実行します

有害な別の種類の不整合があります。それは安定です。 不整合。ビルドが整合性のない安定した状態に達した場合は、 ビルドツールを正常に呼び出しても整合性は復元されません。つまり、 出力は正しくないままです。安定版の不整合な状態 これが、Make や他のビルドツールのユーザーが make clean をタイプする主な理由です。 ビルドツールがこのように失敗したことを検出して復元するには、時間がかかり、非常に面倒な作業になる可能性があります。

概念的には、一貫したビルドを実現する最も簡単な方法は、 すべてのビルドをクリーンビルドにします。 この方法は明らかに時間がかかりすぎて実用的ではありません(ただし、 (リリース エンジニアにとっては有用なもの)であるため、これを有効に活用するには、ビルドツールで 整合性を損なうことなく増分ビルドを実行できます

正しい増分依存関係分析は困難です。前述のように、他の多くのビルドツールは、増分ビルド中に安定した不整合状態を回避するのが苦手です。一方、Bazel では、編集を加えずにビルドツールを正常に呼び出した後、ビルドが一貫した状態になることが保証されます。(期間中にソースファイルを編集しても、 Bazel は、ビルドの結果の一貫性を保証しません。 確認できます。ただし、次のビルドの結果が 復元力があります。)

すべての保証と同様に、細かい条件があります。Bazel で安定した不整合状態になる既知の方法がいくつかあります。増分依存関係分析でバグを意図的に見つけようとした結果生じる問題については、調査を保証するものではありませんが、ビルドツールの通常の使用または「合理的な」使用から生じる安定した不整合状態については、すべて調査し、修正するよう最善を尽くします。

Bazel で安定した不整合状態が検出された場合は、バグを報告してください。

サンドボックス化された実行

Bazel ではサンドボックスを使用して、アクションが密閉型で実行され、 確認します。Bazel は、次のようなサンドボックスでスポーンspawns(大まかに言うとアクション)を実行します。 ツールが機能を実行するために必要な最小限のファイルのみを含む。現在 サンドボックス化は、Linux 3.12 以降で CONFIG_USER_NS オプションを指定すると機能します また、macOS 10.11 以降でもあります。

システムがサンドボックス化をサポートしていない場合、Bazel は警告を表示します。これは、ビルドが完全であることが保証されず、未知の方法でホストシステムに影響する可能性があることを警告するためのものです。この警告を無効にするには、--ignore_unsupported_sandboxing フラグを Bazel に渡します。

Google Kubernetes Engine クラスタノードや Debian などの一部のプラットフォームでは、セキュリティ上の懸念から、ユーザー名前空間はデフォルトで無効になっています。これは、ファイル /proc/sys/kernel/unprivileged_userns_clone を確認することで確認できます。ファイルが存在し、0 が含まれている場合は、sudo sysctl kernel.unprivileged_userns_clone=1 でユーザー名前空間を有効にできます。

システムの設定が原因で、Bazel サンドボックスがルールを実行できない場合があります。この症状は通常、次のようなメッセージが出力される障害です。 namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory。 その場合は、属性で genrule のサンドボックスを無効にし、 --strategy=Genrule=standalone など、次の値を含むルールを --spawn_strategy=standalone。また、 Issue Tracker に送信し、使用している Linux ディストリビューションを明記してください。 今後のリリースで調査して修正を提供します

ビルドのフェーズ

Bazel では、ビルドは 3 つの異なるフェーズで実行されます。ユーザーは、これらのフェーズの違いを理解することで、ビルドを制御するオプションを把握できます(以下を参照)。

読み込みフェーズ

1 つ目は読み込みで、その間に必要なビルド ファイルがすべて 初期ターゲット、およびその依存関係の推移的なクロージャが読み込まれ、 キャッシュに保存されます

Bazel サーバーの起動後の最初のビルドでは、多くの BUILD ファイルがファイル システムから読み込まれるため、通常、読み込みフェーズに数秒かかります。後続のビルドでは、特に BUILD ファイルが変更されていない場合は、読み込みが非常に高速に行われます。

このフェーズで報告されるエラーには、「package not found」、「target not found」、 BUILD ファイル内の語彙や文法の誤り、評価の誤りなど、

分析フェーズ

2 番目のフェーズである分析では、セマンティック分析と検証を行います。 各ビルドルール、ビルド依存関係グラフの構築、 ビルドの各ステップで行う作業を正確に決定できます

読み込みと同様に、分析も全体を計算すると数秒かかります。ただし、Bazel はビルド間で依存関係グラフをキャッシュに保存し、必要なもののみを再分析します。これにより、パッケージが前回のビルドから変更されていない場合は、増分ビルドを非常に高速に行うことができます。

このステージで報告されるエラーには、不適切な依存関係、ルールへの無効な入力、ルール固有のすべてのエラー メッセージが含まれます。

読み込みフェーズと分析フェーズは高速です。このステージでは Bazel が不要なファイル I/O を回避し、実行する作業を決定するために BUILD ファイルのみを読み取るためです。これは設計上の特性であり、Bazel は、読み込みフェーズ上に実装された Bazel の query コマンドなどの分析ツールの優れた基盤となります。

実施フェーズ

ビルドの 3 番目かつ最後のフェーズは実行です。このフェーズでは、必要に応じてコンパイル / リンクなどのツールを再実行し、ビルドの各ステップの出力が入力と一致するようにします。このステップでビルドの大部分の時間が費やされます。時間は、大規模なビルドの場合は数秒から 1 時間以上に及ぶことがあります。このフェーズで報告されるエラーには、ソースファイルがない、ビルドアクションによって実行されたツールのエラー、ツールが想定どおりの出力セットを生成できなかったなどがあります。