Ich weiß, dass ich einen make
Prozess jederzeit unterbrechen kann, ohne den gesamten Quellbaum erneut kompilieren zu müssen. Soweit ich weiß, make
kompiliert es ein Ziel nur, wenn es noch nicht kompiliert ist oder der Quellcode nach der letzten Kompilierung geändert wurde.
Aber wenn ich unterbreche make
, gibt es sicherlich eine oder mehrere (je nach Parallelitätsstufe) halbfertige Binärdateien. Was macht es mit ihnen, wenn ich es das nächste Mal ausführe make
? Oder beendet es das aktuelle Ziel, wenn ich Ctrl+ drücke C, um teilweise kompilierte Binärdateien zu vermeiden?
Antwort1
Vereinfacht ausgedrückt können Sie sich das make
so vorstellen, als ob Sie eine (möglicherweise große) Anzahl von Schritten hätten, wobei jeder Schritt eine Anzahl von Dateien als Eingabe verwendet und eine Datei als Ausgabe erstellt.
Ein Schritt könnte „Kompilieren file.c
nach file.o
“ oder „Verwenden ld
zum Verknüpfen main.o
und file.o
in program
“ sein. Wenn Sie make
mit unterbrechen CtrlC, wird der aktuell ausgeführte Schritt beendet, wodurch die Ausgabedatei, an der gearbeitet wurde, entfernt wird (oder sollte). Normalerweise bleiben keine „halbfertigen Binärdateien“ übrig.
Beim Neustart make
werden die Zeitstempel aller Eingabe- und Ausgabedateien geprüft und die folgenden Schritte erneut ausgeführt:
- eine Eingabedatei hat einen neueren Zeitstempel als die Ausgabedatei
- Die Ausgabedatei existiert nicht
Dies bedeutet im Allgemeinen, dass, wenn die Ausführung eines Schritts lange dauert (das kommt auf modernen Computern selten vor, aber ld
bei großen Programmen konnte der Schritt bei make
seiner Konzeption leicht mehrere Minuten dauern), durch Anhalten und Neustarten make
dieser Schritt von Anfang an gestartet wird.
Die Realität Ihres Durchschnitts Makefile
ist wesentlich komplizierter als die obige Beschreibung, aber die Grundlagen sind dieselben.
Antwort2
Ctrl+ Cbewirkt, SIGINT
dass ein Signal an den laufenden Prozess gesendet wird. Dieses Signal kann vom Prozess abgefangen werden. Im Quelltext von make finden Sie einen Trap für dieses Signal in commands.c
:
/* If we got a signal that means the user
wanted to kill make, remove pending targets. */
if (sig == SIGTERM || sig == SIGINT
... remove childrens ...
/* Delete any non-precious intermediate files that were made. */
remove_intermediates (1);
remove_intermediates()
ist die Bereinigungsfunktion von make
, siehe hier die Definition:
/* Remove all nonprecious intermediate files.
If SIG is nonzero, this was caused by a fatal signal,
meaning that a different message will be printed, and
the message will go to stderr rather than stdout. */
Und später in der angezeigten Funktion werden sie effektiv gelöscht:
status = unlink (f->name);
Abschluss:
Scheuen Sie sich grundsätzlich nicht davor, eine Kompilierung mit zu unterbrechen make
. Wenn es sich nicht um ein nicht abfangbares Signal ( SIGKILL, SIGSEGV, SIGSTOP
) handelt, werden Zwischendateien bereinigt.
Antwort3
Wenn etwas gestoppt wird make
(sei es Strg-C, Herunterfahren oder sogar ein fehlgeschlagener Befehl), bleibt die bereits erledigte Arbeit bestehen. Wenn es neu formuliert wird, make
verhält es sich wie immer: Es findet heraus, was noch getan werden muss (weil eine Datei geändert wurde oder make
nie verarbeitet werden konnte, spielt keine Rolle) und macht mit der Arbeit weiter.
Die obige Beschreibung setzt eindeutig voraus, dass die relevanten Makefile
Abhängigkeiten und Befehle korrekt beschrieben werden, sodass alles, was (neu) erstellt werden muss, korrekt ausgeführt wird.