インクリメンタルビルドとは何か?
インクリメンタルビルドは、変更が触れた部分だけを再ビルドし、それ以外のすべてにはキャッシュされた出力を再利用します。ゼロから作り直すことはしません。
クリーンビルドは毎回すべての作業をやり直します。インクリメンタルビルドは、どの入力が変わったかを追跡し、影響を受けた出力だけを再ビルドして残りを再利用します。数分の再ビルドと数秒の違いがここにあります。
何を再ビルドするかをどう決めるか
buildツールは、入力と出力の間の依存関係(そのビルドグラフ)と以前の出力の状態を追跡します。ファイルを変更すると、そのファイルの出力とその下流のすべてを再ビルドし、無関係な出力には手を触れません。
小さな例
大規模プロジェクトで1つのソースファイルを編集すると、そのファイルとそれをimportする少数のモジュールだけが再コンパイルされます。変更のない数百のモジュールは既存のオブジェクトファイルをそのまま保持するため、buildは数分ではなく数秒で完了します。
なぜCIではこれが難しいのか
インクリメンタルビルドは、以前の出力が存在することに依存します。使い捨てのCI runnerは空の状態で開始するため、ローカルではbuildがインクリメンタルでも、CIでは毎回クリーンになります - リモートcacheが以前の出力を供給しない限りは。
CIで以前の状態を復元する
解決策は、CIに以前の出力を供給することです: リモートのbuild cache(または正しくキー付けされて復元されたbuild出力cache)は、開発者のマシンが持っていたのと同じ状態をrunnerに与えます。これにより、新しいrunnerでもbuildをインクリメンタルにできます。
正しさに関する注意点
インクリメンタルビルドは、ツールがすべての入力を追跡している場合にのみ正しくなります。見落とされた入力(env var、生成されたファイル)は古い出力を残します - これがインクリメンタルのバグが悪名高いほど分かりにくく、クリーンビルドが "魔法のように直してくれる" 理由です。
重要なポイント
- インクリメンタルビルドは以前の出力を再利用し、変更された部分だけを再ビルドします。
- CIのrunnerは空の状態で開始するため、インクリメンタルにするにはリモートcacheが必要です。
- 正しさは、ツールがすべての入力を追跡することに依存します。