Bazel とは何か? スケーラブルで多言語対応の build システム
Bazel は大規模で多言語なコードベース向けに設計された build および test システムで、hermetic な実行と積極的な cache により、高速で再現可能な build を実現します。
Bazel は Google の社内 build ツールに由来し、最も難しいケース、すなわち多くの言語を含む巨大な monorepo をターゲットにしています。中核となる考え方は hermeticity(build は宣言された input のみに依存する)と cache(同一の input は決して再 build されない)であり、この 2 つが相まって、巨大な build ですら高速かつ再現可能にします。
Bazel とは
Bazel はあらゆる規模のプロジェクト向けの build および test ツールで、1 つのリポジトリで多くの言語(C++、Java、Go、Python など)をサポートします。build は、target とその明示的な依存関係を宣言する BUILD ファイルに記述され、Bazel がそれらのコンパイルとテストをオーケストレーションします。
hermeticity と cache
Bazel は各 target に正確な input を宣言することを要求するため、build は周囲の環境ではなく、宣言されたファイルとツールのみに依存します。input が既知であるため、Bazel は input の hash をキーとして出力を cache し、すでに build 済みのものをスキップします。remote cache はこれらの出力をマシン間で共有するため、CI が変更のないコードを再 build することはめったにありません。
使用例
target を label で build および test します。
# build a specific target
bazel build //app:server
# run the tests for a package
bazel test //app/...CI/CD での役割
CI では、Bazel の remote cache とインクリメンタル build は大規模な monorepo にとって画期的です。pipeline は変更されたものだけを再 build および再テストし、しばしば数時間を数分に変えます。これを実現するには永続的または remote な cache が必要ですが、まっさらな CI マシンはデフォルトでこれを持ちません。warm な Bazel cache を維持するマネージド runner は、これらの build をはるかに高速かつ安価にし、auto-retry が一時的な fetch の失敗をならします。
代替ツール
JavaScript の monorepo には、Nx と Turborepo が、より少ないセットアップで同様の cache を提供します。Buck2(Meta 製)と Pants は、同等の大規模 build システムです。Maven、Gradle、Make は、より小規模な単一言語のプロジェクトをよりシンプルに扱います。Bazel は、特に大規模で多言語な規模で真価を発揮します。
重要なポイント
- Bazel は大規模で多言語な monorepo を hermetic に build する。
- 明示的な input により、変更のない build と test をスキップする cache が可能になる。
- CI では、remote/warm な cache が巨大な build を数時間から数分に変える。