Warum verwenden inkrementelle Builds in "make" keine Hashing-Algorithmen?

10

Ich bin ein Anfänger mit makeund ich frage mich, wann ich verwenden soll make clean.

Ein Kollege sagte mir, dass inkrementelle Builds mit makeauf den Zeitstempeln der Dateien basieren. Wenn Sie also eine alte Version einer Datei in Ihrem VCS auschecken, hat sie einen "alten" Zeitstempel und wird als "keine Notwendigkeit zum erneuten Kompilieren dieser Datei" markiert. Dann würde diese Datei nicht in den nächsten Build aufgenommen.
Laut demselben Kollegen wäre dies ein Grund zur Verwendung make clean.

Wie auch immer, ich habe die Antwort auf die Frage "Wann verwenden make clean?" Grob von anderen StackExchange-Fragen erhalten, aber meine andere Frage lautet dann:

Warum makestützen sich inkrementelle Builds mithilfe von Dateizeitstempeln und nicht beispielsweise auf SHA-1? Git zeigt zum Beispiel, dass wir erfolgreich feststellen können, ob eine Datei mit dem SHA-1 geändert wurde.
Ist es für Geschwindigkeitsprobleme?

Filaton
quelle
5
makewurde in den 70er Jahren erstellt. SHA-1 wurde in den 90er Jahren erstellt. Git wurde in 00er erstellt. Das Letzte, was Sie wollen, ist, dass einige obskure Builds, die 30 Jahre lang funktionierten, plötzlich versagten, weil sich jemand entschied, mit einem bewährten System ganz modern zu werden.
Ordentlicher
1
Das ständige Hashing der Dateien ist langsam. Ich denke, Git verwendet auch Dateisystem-Metadaten, um die Überprüfung auf geänderte Dateien zu optimieren.
CodesInChaos
4
Die ursprüngliche Lösung, die auf Dateidaten basiert, ist sehr einfach, benötigt keine zusätzlichen Dateien zum Speichern der Hash-Codes und hat über mehrere Jahrzehnte bemerkenswert gut funktioniert. Warum sollte jemand eine gut funktionierende Lösung durch eine kompliziertere ersetzen? Darüber hinaus weisen die meisten VCS-Systeme von AFAIK ausgecheckten Dateien das "Auscheckdatum" zu, sodass geänderte Dateien eine Neukompilierung ohne "sauber machen" korrekt verursachen.
Doc Brown
@Ordous: Amüsant, aber ist es hier relevant? Software rostet nicht; es gibt aus, weil jemand etwas in der Umgebung verändert hat. Es sei denn, sie haben es nicht getan. In diesem Fall sollte es immer noch funktionieren.
Robert Harvey
1
@ RobertHarvey Natürlich ist es das! Sicher, wenn Sie Ihre nicht aktualisieren, makewird Ihre Software nicht kaputt gehen, makebemüht sich jedoch eher um Abwärtskompatibilität in neuen Versionen. Das Ändern des Kernverhaltens ohne guten Grund ist so ziemlich das Gegenteil davon. Und die Daten zeigen, warum es ursprünglich nicht für die Verwendung von SHA-1 hergestellt wurde oder warum es nicht einfach war, es nachzurüsten, als es verfügbar wurde (war zu diesem makeZeitpunkt bereits Jahrzehnte alt).
Ordentlicher

Antworten:

7

Ein offensichtliches (und wohl oberflächliches) Problem wäre, dass das Build-System die Hashes der Dateien aufzeichnen müsste, die für den letzten Build verwendet wurden. Während dieses Problem sicherlich gelöst werden könnte, würde es einen Seitenspeicher erfordern, wenn die Zeitstempelinformationen bereits im Dateisystem vorhanden sind.

Im Ernst, der Hash würde jedoch nicht die gleiche Semantik vermitteln. Wenn Sie wissen, dass die Datei T aus der Abhängigkeit D mit dem Hash H 1 erstellt wurde, und dann herausfinden, dass D jetzt mit H 2 hasht , sollten Sie T neu erstellen ? Wahrscheinlich ja, aber es könnte auch sein, dass H 2 tatsächlich auf eine ältere Version der Datei verweist . Zeitstempel definieren eine Reihenfolge, während Hashes nur für die Gleichheit vergleichbar sind.

Eine Funktion, die Zeitstempel unterstützen, besteht darin, dass Sie den Zeitstempel einfach aktualisieren können (z. B. mithilfe des POSIX-Befehlszeilenprogramms touch), um zu glauben make, dass sich eine Abhängigkeit geändert hat oder - was interessanter ist - ein Ziel neuer ist als es tatsächlich ist. Während das Spielen damit eine großartige Gelegenheit ist, sich in den Fuß zu schießen, ist es von Zeit zu Zeit nützlich. In einem Hash-basierten System benötigen Sie Unterstützung vom Build-System selbst, um die interne Datenbank der für den letzten Build verwendeten Hashes zu aktualisieren, ohne tatsächlich etwas zu erstellen.

Während sicherlich ein Argument für die Verwendung von Hashes über Zeitstempel vorgebracht werden könnte, ist mein Punkt, dass sie keine bessere Lösung sind, um dasselbe Ziel zu erreichen, sondern eine andere Lösung, um ein anderes Ziel zu erreichen. Welches dieser Ziele wünschenswerter ist, könnte zur Debatte stehen.

5gon12eder
quelle
1
Während sich die Semantik zwischen Hashes und Zeitstempeln unterscheidet, ist dies in diesem Fall normalerweise irrelevant, da Sie höchstwahrscheinlich einen Build basierend auf den aktuellen Dateien wünschen, unabhängig von deren Alter.
Axl
Das meiste, was Sie sagen, ist richtig. Ein gut implementiertes Build-System, das Hashes wie Google Blaze / Bazel verwendet (die interne Version von Blaze, die Open Source-Version ist Bazel), schlägt jedoch die Hosen eines zeitgestempelten Systems wie Make. Das heißt, Sie müssen viel Aufwand in wiederholbare Builds investieren, damit es immer sicher ist, alte Build-Artefakte zu verwenden, anstatt sie neu zu erstellen.
Btilly
Das Mapping hier ist nicht viele zu eins, es ist eins zu eins. Wenn Djetzt Hashes ausgeführt H2werden und keine Ausgabe erstellt T2wurde D@H2, müssen Sie diese erstellen und speichern. Danach können Sie unabhängig davon, in welcher Reihenfolge Dzwischen den Zuständen H1und umgeschaltet H2wird, die zwischengespeicherte Ausgabe verwenden.
Asad Saeeduddin
1

Das Hashing eines gesamten Projekts ist sehr langsam. Sie müssen jedes einzelne Byte jeder einzelnen Datei lesen. Git hasht nicht jede Datei jedes Mal, wenn Sie eine ausführen git status. Bei VCS-Kassen wird die Änderungszeit einer Datei normalerweise nicht auf die ursprünglich erstellte Zeit festgelegt. Eine Sicherungswiederherstellung würde erfolgen, wenn Sie dies tun. Der ganze Grund, warum Dateisysteme Zeitstempel haben, liegt in solchen Anwendungsfällen.

Ein Entwickler wird normalerweise ausgeführt, make cleanwenn sich eine Abhängigkeit, die nicht direkt vom Makefile verfolgt wird, ändert. Ironischerweise schließt dies normalerweise das Makefile selbst ein. Es enthält normalerweise auch Compilerversionen. Abhängig davon, wie gut Ihr Makefile geschrieben ist, kann es externe Bibliotheksversionen enthalten.

Dies sind die Dinge, die normalerweise aktualisiert werden, wenn Sie ein Versionskontroll-Update durchführen. Daher haben die meisten Entwickler die Gewohnheit, gleichzeitig ein Update durchzuführen make clean, sodass Sie wissen, dass Sie von einem sauberen Plan ausgehen. Sie können davonkommen, ohne es oft zu tun, aber es ist wirklich schwierig, die Zeiten vorherzusagen, die Sie nicht können.

Karl Bielefeldt
quelle
Sie können Dateisysteme wie ZFS verwenden, bei denen sich die Kosten für das Hashing über die Zeit amortisieren, in der die Dateien geändert werden, anstatt beim Erstellen auf einmal bezahlt zu werden.
Asad Saeeduddin
1

Einige Punkte zu Hashes und Zeitstempeln in Build-Systemen:

  1. Wenn Sie eine Datei auschecken, sollte der Zeitstempel auf die aktuelle Zeit aktualisiert werden, wodurch eine Neuerstellung ausgelöst wird. Was Ihr Kollege beschreibt, ist normalerweise kein Fehlermodus von Zeitstempelsystemen.
  2. Zeitstempel sind geringfügig schneller als Hashes. Ein Zeitstempelsystem muss nur den Zeitstempel überprüfen, während ein Hashsystem den Zeitstempel und dann möglicherweise den Hash überprüfen muss.
  3. Make ist leicht und in sich geschlossen. Um (2) zu überwinden, führen hashebasierte Systeme normalerweise einen Hintergrundprozess zum Überprüfen von Hashes aus (z. B. Facebooks Watchman ). Dies steht im Widerspruch zu den Designzielen (und der Geschichte) von Make.
  4. Hashes verhindern unnötige Neuerstellungen, wenn sich ein Zeitstempel geändert hat, nicht jedoch der Inhalt. Dies gleicht häufig die Kosten für die Berechnung des Hash aus.
  5. Mit Hashes können Artefakt-Caches projektübergreifend und über ein Netzwerk gemeinsam genutzt werden. Dies gleicht wiederum die Kosten für die Berechnung von Hashes mehr als aus.
  6. Zu den modernen Hash-basierten Build-Systemen gehören Bazel (Google) und Buck (Facebook).
  7. Die meisten Entwickler sollten die Verwendung eines Hash-basierten Systems in Betracht ziehen, da sie nicht dieselben Anforderungen haben wie diejenigen, unter denen Make entwickelt wurde.
sdgfsdh
quelle