2016-03-20 4 views
1

Ich habe ein einfaches Makefile, das einige Daten verarbeitet, um einige andere Daten zu erzeugen. Es gibt viele Schritte, die zeitaufwendig sein können, daher meine Verwendung von make. Einer der ersten Schritte (z. B. Ziele) besteht darin, eine Eingabedatei von einer Website herunterzuladen. Diese Website wird jedoch nur jeden Tag aktualisiert. Während ich an der Verarbeitung arbeite, möchte ich nicht jedes Mal die Datei herunterladen müssen (und damit alle Zwischenverarbeitungsschritte durchführen), aber am nächsten Tag, wenn es eine neue Eingabedatei gibt, möchte ich zum Herunterladen bringen das und arbeite damit.Soll ein Ziel erneut ausgeführt werden, wenn das Ziel mehr als X Stunden alt ist?

Gibt es trotzdem zu sagen make "Wenn diese Datei mehr als X Stunden/etc alt ist, dann 'neu aufbauen"?

Antwort

1

Make selbst unterstützt das nicht, also muss es ein Ziel ausführen, das das Download-Datum überprüft und den Download nur durchführt, wenn die Datei alt ist.

Ich nehme an, dass Sie Standard Unix-Dienstprogramme zur Verfügung haben. Wenn Sie dies unter Windows benötigen, können Sie einen der vielen Ports von Linux/POSIX-Dienstprogrammen für Windows verwenden.

Wenn Sie nicht möchten, dass das Datum der lokalen Datei mit dem Datum auf dem Server übereinstimmt, können Sie die Änderungszeit der Datei verwenden.

Wenn die lokale Kopie dem Serverdatum entsprechen soll, können Sie die Datei ctime testen. Das kann sich aus anderen Gründen ändern (z. B. wenn Sie die Datei verschieben), aber es kann für diesen Anwendungsfall gut genug sein.

data-file: 
     test -n "$$(find [email protected] -ctime -1)" || \ 
     rm [email protected] && \ 
     wget -N http://example.com/data-file 

Ein alternativer Ansatz, wenn Sie nicht auf dem Zeitstempel der Datei selbst verlassen können, ist eine Zeitstempel-Datei zu erstellen. Abhängigkeiten hängen von data-file.stamp ab, abhängig vom Datum des Downloads.

data-file: 
     test -n "$$(find [email protected] -mtime -1)" || \ 
     rm [email protected] && \ 
     wget -N http://example.com/data-file 
data-file.stamp: data-file 
     touch data-file.stamp 

Darüber hinaus, wenn der Server unterstützt wird, können Sie es Ihnen sagen, um die Datei zu füttern nur, wenn seine Kopie als Ihr neuer ist.

data-file: 
     test -n "$$(find [email protected] -mtime -1)" || \ 
     curl --remote-time --time-cond http://example.com/data-file 

Alternativ können Sie die lokale Datei auch nicht ändern, wenn sich die Serverkopie nicht geändert hat.

data-file: 
     cd tmp && wget http://example.com/data-file 
     if cmp -s tmp/data-file [email protected]; then rm tmp/data-file; else mv tmp/data-file [email protected]; fi 

Einige dieser Ansätze können kombiniert werden.

1

Meine Strategie wäre, eine Regel zu schreiben, die immer ausgelöst wird und in den Befehlen der Regel die Regeneration überspringt, wenn das Ziel jung genug ist. Übung für den Leser und all das :-)

Dies funktioniert, weil make ein Ziel als aktuell betrachtet, wenn eine passende Regel ausgeführt wurde, auch wenn sich der Zeitstempel nicht geändert hat.

Verwandte Themen