
2026/04/14 3:50
# フォアファイアのビルドを 17% 高速化する手順 Mozilla のビルド環境を最適化し、**17% のパフォーマンス向上**を実現するための手順をご紹介します: - ビルドシステムと依存関係を最新の状態に更新してください。 - `MOZ_MAKEFLAGS` を適切に設定して(例:`-j$(nproc)`)、並列ビルドプロセスを有効にしてください。 - `-O2` や `-O3` といった最適化されたコンパイラフラグを、状況に応じて使用してください。 - 不要な負荷を削減するために、古くなったビルドアーティファクトを削除してください。 - インクリメンタルビルドにおいては、プリビルドされたツールキットやキャッシュされたオブジェクトファイルの利用を検討してください。 これらの変更を加えることで、コード品質を損なうことなくコンパイル時間を大幅に短縮できます。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
このアップデートは、Firefox のビルドシステムへの重要な修正を導入し、Buildcache Lua プラグインシステムを介して WebIDL バインディングコードの生成に対して有効なキャッシュ化を実現します。歴史的に、この Python ベースのステップ(
python3 -m mozbuild.action.webidl)は ccache や sccache のような標準的なコンパイラキャッシュと互換性がありませんでした。これは任意のコマンドを効果的にラップできないためです。修正内容は dom/bindings/Makefile.in に条件付きラッパーを追加するものであり、Buildcache を使用する際にのみ有効化されます(MOZ_USING_BUILDCACHE が定義されている場合)。これにより呼び出しは buildcache python3 -m mozbuild.action.webidl ... へと変換されます。Buildcache の Lua ラッパー (webidl.lua) は .webidl ファイルや Python スクリプトなどの入力を、および file-lists.json と codegen.json から出力を識別し、ハッシュ化には direct_mode を使用します。Linux におけるタイミング測定では、このラッパーがなかった場合に Buildcache が使用されなかった場合の約 3m27sに対して、ccache(約 3m21s)および sccache(約 2m49s)が以前より優れていました。Lua ラッパーを有効にすると、ウォームビルド時間は約 1m12s–1m27s に低下します。設定には、central を更新するか buildcache-wrappers をクローンし、~/.buildcache/config.json で lua_paths を構成する(または mozconfig を通じて BUILDCACHE_LUA_PATH を設定)ことを必要とします。構成には、Rust クレートからの大規模なエントリに対応するための 2.5 GB の max_local_entry_size が含まれています。現在では概念実証として機能していますが、この最適化は将来の Firefox 開発において大きな可能性を示しており、反復サイクルの加速とより高速なアップデートをもたらすとともに、他の確定論的コード生成ステップへの拡張の可能性もあります。本文
前回の投稿で、buildcache が ccache や sccache と比べて独自の特性をいくつか備えていることを述べました。その一つが Lua プラグインシステムであり、従来のコンパイラーとは異なる種類のプログラムに対してカスタムラッパーを作成することを可能にします。Bug 2027655 がマージされたことで、この機能を Mozilla Firefox の WebIDL バイニングコード生成のキャッシュ化に応用できるようになりました。
WebIDL ステップとは何か?
Firefox をビルドする際、初期段階の一つとして
python3 -m mozbuild.action.webidl が実行され、数百個の .webidl ファイルから C++ のバイニングコードを生成します。これにより、ヘッダーファイル、cpp ファイル、前方宣言、イベントの実装など、数千件の出力ファイルを出力します。このステップ自体はそれほど時間がかからないわけではありませんが、すべての clobber ビルド(キャッシュリセットビルド)において実行される点に問題があります。かつ、同一の入力に対して出力が完全に決定論的であるため、これはまさにキャッシングに適した対象と言えます。
課題は、このステップにコンパイラーキャッシュが渡されなかったことです。buildcache は実際のコマンド呼び出しのみをラッパーしているだけで、Python によるコード生成段階には対応していませんでした。
今回の変更内容
Bug 2027655 で提案された修正はシンプルです。
dom/bindings/Makefile.in において、$(CCACHE) を py_action の呼び出し時に条件付きでコマンドラッパーとして渡すようになりました:
WEBIDL_CCACHE= ifdef MOZ_USING_BUILDCACHE WEIDL_CCACHE=$(CCACHE) endif webidl.stub: $(codegen_dependencies) $(call py_action,webidl $(relativesrcdir),$(srcdir),,$(WEBIDL_CCACHE)) @$(TOUCH) $@
config/makefiles/functions.mk に定義される py_action マクロは Python によるビルドアクションを実行します。コマンドラッパーを第四个引数として渡す機能も、このバグ修正によって追加されました。buildcache をコンパイラーキャッシュとして設定している場合、WebIDL アクションは単なる python3 -m mozbuild.action.webidl ... の代わりに、buildcache python3 -m mozbuild.action.webidl ... という形式で呼び出されるようになります。これこそが buildcache が捕捉する必要な情報です。
なお、
ifdef MOZ_USING_BUILDCACHE というガード条件には注意が必要です。これは ccache や sccache と異なり、arbitrary コマンドのキャッシング機能を提供するのは buildcache のみであるため(その実現手段は Lua ラッパー経由)、buildcache 固有の設定となっています。
Lua ラッパー
buildcache の Lua プラグインシステムを活用することで、ネイティブには対応していないプログラムの扱い方を定義するスクリプトを作成できます。WebIDL コード生成用のラッパー
webidl.lua では、buildcache に対して以下の問いに答える必要があります:
- このコマンドを処理できるか?引数リスト中で
にマッチするかを確認します。mozbuild.action.webidl - 入力は何か?
ソースファイルに加え、Python のコード生成スクリプトが該当します。これらは.webidl
が生成するmach
および、前回の実行における Python 依存関係を追跡したfile-lists.json
から取得されます。codegen.json - 出力は何か?生成されたバイニングヘッダー、cpp ファイル、イベントファイル、そしてコード生成の状態ファイルを挙げることができます。これらもまた
から導出されます。file-lists.json
これらの情報を基に buildcache は入力のハッシュを計算しキャッシュを確認し、ヒットすればキャッシュされた出力を再使用するか、あるいは実際のコマンドを実行して結果を保存します。
なお、このラッパーでは buildcache の
direct_mode 能力を利用しています。これは C プレプロセッサ処理後の出力に依存せず、入力ファイルを直接ハッシュ化することを意味します。当件のように C プレプロセッサではなく、.webidl ファイルを読み取る Python スクリプトを扱う場合、このアプローチが適切です。
数値結果
Linux 環境下における
./mach build のビルド時間を、各行で冷たいキャッシュ(空のキャッシュ)および温かいキャッシュ(充填されたキャッシュ)条件下での汚損ビルド(clobber build)を示します:
| ツール | 冷たく (cold) | 温かく (warm) | プラグインあり(with plugin) |
|---|---|---|---|
| none | 5m35s | n/a | n/a |
| ccache | 5m42s | 3m21s | n/a |
| sccache | 9m38s | 2m49s | n/a |
| buildcache | 5m43s | 1m27s | 1m12s |
「プラグインあり」の列は、
webidl.lua ラッパーが有効化された buildcache の結果です。これによりさらに 15 秒の削減ができ、合計時間は 1 分 12 秒になります。これは単独では革命的な改善ではありませんが、このメカニズムの有効性を示す証拠と言えます。WebIDL ステップは、この待遇を受ける最初の Python アクションの一つに過ぎず、ビルドプロセス内には同様のアプローチが有効な他のコード生成ステップも存在します。
より大域的に見れば、これらの数値は buildcache が温かいビルドにおいて圧倒的な性能向上をもたらすことを示しています。クリーンビルドの 5 分 35 秒から、キャッシュ再構築では 1 分 12 秒へと短縮されるのは、編集—コンパイル—テストサイクルを大幅に改善します。
これらは単一マシンの単一回路の実験であり厳密なベンチマークではありませんが、傾向は明確です。
設定方法
すでに
mach と buildcache を併用している場合、Makefile の変更は中央リポジトリの最新バージョンを更新することで利用可能になります。Lua ラッパーを有効化するには、buildcache-wrappers リポジトリをクローンし、~/.buildcache/config.json の lua_paths 経由で buildcache にそのパスを指定します:
{ "lua_paths": ["/path/to/buildcache-wrappers/mozilla"], "max_cache_size": 10737418240, "max_local_entry_size": 2684354560 }
alternatively、環境変数
BUILDCACHE_LUA_PATH を設定することも可能です。そのための適切な場所は mozconfig です:
mk_add_options "export BUILDCACHE_LUA_PATH=/path/to/buildcache-wrappers/mozilla/"
大きな
max_local_entry_size(2.5 GB)は、一部の Rust crates が非常に大きなキャッシュエントリを生成するため必要な設定です。
今後の展開
本件の興味深い点は Lua プラグインシステムそのものです。WebIDL 用のラッパーは概念実証(PoC)に過ぎませんが、既知の入力を受け取り既知の出力を生成する任意の決定論的なビルドステップに対して、同じ手法が適用可能です。Firefox のビルドには他にも同様の待遇を与えうるコード生成アクションが存在し、これらについても今後調査を続けます。