Wie wird die Kompilierung fortgesetzt?

11

Ich weiß, dass ich einen makeProzess jederzeit unterbrechen kann, ohne den gesamten Quellbaum erneut kompilieren zu müssen. Wie ich weiß, makekompiliert ein Ziel nur, wenn es noch nicht kompiliert wurde oder der Quellcode nach der letzten Kompilierung geändert wurde.
Aber wenn ich unterbreche make, wird es sicherlich eine oder mehrere (je nach Parallelitätsstufe) halbfertige Binärdateien geben. Was macht es mit ihnen, wenn ich das nächste Mal renne make? Oder beendet es das aktuelle Ziel, wenn ich Ctrl+ drücke C, um teilweise kompilierte Binärdateien zu vermeiden?

Psimon
quelle
2
Meistens müssen Sie sich nur Sorgen machen, wenn sich der Computer unerwartet ausschaltet. Ein paar Mal gelang es meinem Ubuntu, in einen Kernel-Deadlock (oder was auch immer es ist) zu geraten und halbfertige Binärdateien zu hinterlassen, was mehr als zwei Stunden verschwendete.
Alvin Wong

Antworten:

12

In einfachen Worten, Sie können sich makeeine (möglicherweise große) Anzahl von Schritten vorstellen, wobei jeder Schritt eine Anzahl von Dateien als Eingabe verwendet und eine Datei als Ausgabe erstellt.

Ein Schritt könnte "Kompilieren file.cnach file.o" oder "Verwenden ldzum Verknüpfen main.ound file.oIn program" sein. Wenn Sie unterbrechen makemit CtrlC, dann wird die aktuell ausgeführten Schritt beendet , die (oder sollte) , um die Ausgabedatei entfernen sie arbeitete. Es bleiben normalerweise keine "halbfertigen Binärdateien" zurück.

Beim Neustart makewerden die Zeitstempel aller Eingabe- und Ausgabedateien angezeigt 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 das Stoppen und Neustarten dieses Schritts von vorne beginnt, ldwenn makedie Ausführung eines Schritts lange dauert (dies ist auf modernen Computern selten, aber der Schritt für große Programme kann beim Entwurf leicht viele Minuten dauern ) make.

Die Realität Ihres Durchschnitts Makefileist erheblich komplizierter als die obige Beschreibung, aber die Grundlagen sind dieselben.

Greg Hewgill
quelle
8

Ctrl+ Cbewirkt SIGINT, dass a an den laufenden Prozess gesendet wird. Dieses Signal kann vom Prozess abgefangen werden. Im Quellcode von make finden Sie eine Falle 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 Definition hier:

/* 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 Funktion, die Sie sehen, werden sie effektiv gelöscht:

status = unlink (f->name);

Fazit: Im Allgemeinen keine Angst davor haben, eine Kompilierung mit zu unterbrechen make. Wenn es sich nicht um ein nicht abfangbares Signal ( SIGKILL, SIGSEGV, SIGSTOP) handelt, werden Zwischendateien bereinigt.

Chaos
quelle
1
SIGSEGVist auf vielen Unices fangbar.
Chris Down
1

Wenn etwas stoppt make(sei es Strg-C, Herunterfahren oder sogar ein fehlgeschlagener Befehl), bleibt die bereits geleistete Arbeit bestehen. Wenn angepasst, makefunktioniert dies wie immer: Es wird herausgefunden, was noch zu tun ist (weil eine Datei geändert wurde odermake nie verarbeitet werden muss, spielt keine Rolle) und fährt mit dem Job fort.

Die obige Beschreibung setzt eindeutig voraus, dass die relevanten Makefiles die Abhängigkeiten und Befehle beschreiben, die korrekt ausgeführt werden sollen. Alles, was (neu) gemacht werden muss, ist.

vonbrand
quelle