私はmake
の初心者であり、make clean
をいつ使用するかについて疑問に思っています。
ある同僚は、make
を使用したインクリメンタルビルドはファイルのタイムスタンプに基づいていると私に言った。そのため、VCSで古いバージョンのファイルをチェックアウトすると、そのファイルには「古い」タイムスタンプが付けられ、「このファイルを再コンパイルする必要はありません」とマークされます。その後、そのファイルは次のビルドに含まれません。
同じ同僚によれば、make clean
を使用するのはそのためです。
とにかく、私は他のStackExchangeの質問から「make clean
を使用するタイミング」という質問への回答を大まかに得ましたが、他の質問は次のとおりです。
make
を使用したインクリメンタルビルドが、たとえばSHA-1ではなくファイルのタイムスタンプに依存するのはなぜですか?たとえば、Gitは、SHA-1を使用してファイルが変更されたかどうかを正常に判断できることを示しています。
速度の問題ですか?
明白な(そしておそらく表面的な)問題は、ビルドシステムが最後のビルドに使用されたファイルのハッシュの記録を保持しなければならないことです。この問題は確実に解決できますが、タイムスタンプ情報がファイルシステムにすでに存在する場合は、サイドストレージが必要になります。
しかし、もっと真剣に、ハッシュは同じセマンティクスを伝えません。そのファイルを知っている場合 T 依存関係から構築されました D ハッシュ付き H1 そしてそれを見つける D 今ハッシュする H2、再構築する必要があります T?おそらくそうですが、それもそうかもしれません H2 実際には、ファイルの古いバージョンを指します。タイムスタンプは順序を定義しますが、ハッシュは同等である場合にのみ比較できます。
タイムスタンプがサポートする機能は、touch
をだまして次のことを考えさせるために、タイムスタンプを単に更新できることです(たとえば、POSIXコマンドラインユーティリティ make
を使用)。依存関係が変更された、または興味深いことに、ターゲットが実際よりも新しい。これで遊ぶことは足に自分を撃つ絶好の機会ですが、時々役立ちます。ハッシュベースのシステムでは、実際には何もビルドせずに、最後のビルドに使用されたハッシュの内部データベースを更新するために、ビルドシステム自体からのサポートが必要になります。
タイムスタンプよりもハッシュを使用することについては確かに議論の余地はありますが、私の目標は、同じ目標を達成するためのより良い解決策ではなく、異なる目標を達成するための異なる解決策であるということです。これらの目標のどちらが望ましいかは、議論の余地があります。
ビルドシステムのハッシュとタイムスタンプに関するいくつかのポイント:
プロジェクト全体のハッシュは非常に遅いです。すべてのファイルのすべての1バイトを読み取る必要があります。 Gitは、git status
を実行するたびにすべてのファイルをハッシュするわけではありません。また、VCSチェックアウトは通常、ファイルの変更時刻を元の作成時刻に設定しません。バックアップを復元する場合は、注意してください。ファイルシステムにタイムスタンプがあるのは、このようなユースケースのためです。
依存関係がMakefileの変更によって直接追跡されない場合、開発者は通常make clean
を実行します。皮肉なことに、これには通常Makefile自体が含まれます。通常、コンパイラのバージョンも含まれます。 Makefileの作成状況によっては、外部ライブラリのバージョンを含めることができます。
これらは、バージョン管理の更新を行うときに更新される傾向がある種類のことなので、ほとんどの開発者はmake clean
を同時に実行する習慣を身に付けるだけなので、クリーンな状態から開始できます。スレート。多くの場合それをしなくても逃げることができますが、できない時間を予測することは本当に難しいです。