「make」の増分ビルドでハッシュアルゴリズムが使用されないのはなぜですか?


10

私はの初心者でmakeあり、いつ使用するか迷っていますmake clean

ある同僚は、増分ビルドmakeはファイルのタイムスタンプに基づいていると私に言った。そのため、VCSで古いバージョンのファイルをチェックアウトすると、「古い」タイムスタンプが付けられ、「このファイルを再コンパイルする必要がない」とマークされます。その後、そのファイルは次のビルドに含まれません。
同じ同僚によると、それを使用する理由になりますmake clean

とにかく、私make cleanは他のStackExchangeの質問から「いつ使用するか」という質問への答えを大まかに得ましたが、私のもう1つの質問は次のとおりです。

makeたとえば、SHA-1ではなくファイルのタイムスタンプに依存してインクリメンタルビルドを行うのはなぜですか?たとえば、Gitは、SHA-1を使用してファイルが変更されたかどうかを正常に判断できることを示しています。
速度の問題ですか?


5
make70年代に作成されました。SHA-1は90年代に作成されました。Gitは00年代に作成されました。あなたが望む最後のことは、誰かが試されてテストされたシステムですべてを最新のものにすることを決めたので、30年間働いていたいくつかのあいまいなビルドが突然失敗することです。
Ordous、

1
常にファイルをハッシュするのは遅いです。gitもファイルシステムメタデータを使用して、変更されたファイルのチェックを最適化すると思います。
CodesInChaos 2016年

4
ファイルの日付に基づく元のソリューションは非常に単純で、ハッシュコードを保存するために追加のファイルを必要とせず、数十年にわたって非常によく機能しました。なぜ誰かがうまく機能するソリューションをより複雑なソリューションに置き換える必要があるのですか?さらに、AFAIKのほとんどのVCSシステムでは、チェックアウトされたファイルに「チェックアウト日」が割り当てられているため、変更されたファイルは、「make clean」なしで正しく再コンパイルされます。
Doc Brown

@Ordous:おもしろいですが、ここでは関連がありますか?ソフトウェアは錆びません。誰かが周囲の環境で何かを変えたのでそれは出ます。彼らがそうしなかった場合を除き、その場合でもそれはまだ機能するはずです。
Robert Harvey、

1
@RobertHarveyもちろんです!もちろん、更新しないとmakeソフトウェアが壊れることはありませんが、make新しいバージョンで下位互換性を維持するための努力がなされています。正当な理由なくコアの動作を変更することは、それとは正反対です。そして、日付は、なぜそれがSHA-1を最初に使用するように作られていないのか、またはそれが利用可能になったときにそれを改良するのが容易ではなかった理由を示してmakeいます(すでに数十年前のことです)。
Ordous、

回答:


7

明白な(そしておそらく表面的な)問題は、ビルドシステムが最後のビルドに使用されたファイルのハッシュの記録を保持しなければならないことです。この問題は確かに解決できますが、タイムスタンプ情報がファイルシステムにすでに存在する場合は、サイドストレージが必要になります。

しかし、もっと真剣に、ハッシュは同じ意味論を伝えません。ファイルTが依存関係DからハッシュH 1で構築されたことがわかっていて、DH 2にハッシュされることがわかった場合、Tを再構築する必要がありますか?おそらくそうですが、H 2が実際に古いバージョンのファイルを参照している可能性もあります。タイムスタンプは順序を定義しますが、ハッシュは同等である場合にのみ比較できます。

タイムスタンプがサポートする機能は、依存関係が変更されたか、またはさらに興味深いことに、ターゲットがより最近であるtouchと思い込ませるために、タイムスタンプを単に更新することです(たとえば、POSIXコマンドラインユーティリティを使用)。make実際よりも。これで遊ぶことは、自分を足に撃ち込む絶好の機会ですが、時々役立ちます。ハッシュベースのシステムでは、実際には何もビルドせずに、最後のビルドに使用されたハッシュの内部データベースを更新するために、ビルドシステム自体からのサポートが必要になります。

タイムスタンプよりもハッシュを使用することについては確かに議論の余地がありますが、私の目標は、ハッシュが同じ目標を達成するためのより良い解決策ではなく、異なる目標を達成するための異なる解決策であるということです。これらの目標のどちらがより望ましいかは、議論の余地があります。


1
ハッシュとタイムスタンプではセマンティクスが異なりますが、現在のファイルに基づくビルドが必要になる可能性が高いため、この場合は通常は関係ありません。
axl 2016年

あなたが言うことのほとんどは正しいです。ただし、Google blaze / bazel(blazeの内部バージョン、オープンソースはbazelです)のようなハッシュを使用する適切に実装されたビルドシステムは、Makeのようなタイムスタンプ付きシステムのパンツを打ち負かしています。それはあなたが配置する必要があります、と述べたたくさん常にではなく再構築よりも古いビルド成果物を使用しても安全であるように構築し、再現に力を。
btilly '25年

ここでのマッピングは多対1ではなく、1対1です。場合はD、今までハッシュH2、そしてあなたには、いくつかの出力がありませんT2から構築しD@H2、あなたはそれを生成して保存する必要があります。その後、との状態がどの順序でD切り替わっても、キャッシュされた出力を使用できます。H1H2
Asad Saeeduddin 2017年

1

プロジェクト全体のハッシュは非常に遅いです。すべてのファイルのすべてのバイトを読み取る必要があります。Gitは、git statusいずれかを実行するたびにすべてのファイルをハッシュするわけではありません。また、VCSチェックアウトは通常、ファイルの変更時刻を元の作成時刻に設定しません。バックアップを復元する場合は、注意してください。ファイルシステムにタイムスタンプがあるのは、このようなユースケースのためです。

通常、開発者はmake clean、Makefileの変更によって依存関係が直接追跡されていない依存関係を実行します。皮肉なことに、これには通常Makefile自体が含まれます。通常、コンパイラのバージョンも含まれます。Makefileがどの程度適切に記述されているかによって、外部ライブラリバージョンが含まれる場合があります。

これらは、バージョン管理の更新を行うときに更新される傾向がある種類のものなので、ほとんどの開発者make cleanはを同時に実行する習慣を身につけるだけなので、白紙の状態から始めていることがわかります。多くの場合それをせずに逃げることができますが、できない時間を予測することは本当に難しいです。


ZFSのようなファイルシステムを使用できます。ハッシュのコストは、ビルド時に一度に支払われるのではなく、ファイルが変更されている間に償却されます。
Asad Saeeduddin 2017年

1

ビルドシステムでのハッシュとタイムスタンプに関するいくつかのポイント:

  1. ファイルをチェックアウトすると、タイムスタンプが現在の時刻に更新され、再構築がトリガーされます。同僚が説明するのは、通常、タイムスタンプシステムの障害モードではありません。
  2. タイムスタンプはハッシュよりもわずかに高速です。タイムスタンプシステムはタイムスタンプのみをチェックする必要がありますが、ハッシュシステムはタイムスタンプをチェックし、次にハッシュをチェックする必要があります。
  3. Makeは軽量で自己完結型になるように設計されています。(2)を克服するために、hashベースのシステムは通常、ハッシュをチェックするためのバックグラウンドプロセスを実行します(例:FacebookのWatchman)。これは、Makeの設計目標(および履歴)に反しています。
  4. ハッシュは、タイムスタンプが変更されたが内容は変更されなかった場合に、不要な再構築を防止します。多くの場合、これはハッシュを計算するコストを相殺します。
  5. ハッシュを使用すると、アーティファクトキャッシュをプロジェクト間およびネットワーク経由で共有できます。繰り返しますが、これはハッシュの計算コストを相殺する以上のものです。
  6. 最新のハッシュベースのビルドシステムには、Bazel(Google)とBuck(Facebook)が含まれます。
  7. Makeが設計されたときと同じ要件がないため、ほとんどの開発者はハッシュベースのシステムの使用を検討する必要があります。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.