Comment faire continuer la compilation?

11

Je sais que je peux interrompre un makeprocessus à tout moment sans avoir à recompiler à nouveau l’arborescence source entière. Comme je le sais, makene compile une cible que si elle n'est pas encore compilée, ou si le code source est modifié après la dernière compilation.
Mais si j'interromps make, il y aura sûrement un ou plusieurs binaires semi-prêts (selon le niveau de concurrence). Que fait-il avec eux la prochaine fois que je courrai make? Ou termine-t-il la cible actuelle lorsque j'appuie sur Ctrl+ Cpour éviter les binaires partiellement compilés?

psimon
la source
2
La plupart du temps, vous n'avez à vous inquiéter que si l'ordinateur s'est éteint de manière inattendue. Quelques fois, mon Ubuntu a réussi à se retrouver dans une impasse du noyau (ou quoi que ce soit) et a laissé des binaires à moitié prêts, ce qui a fini par perdre plus de deux heures.
Alvin Wong

Réponses:

12

En termes simples, vous pouvez penser makeà avoir un nombre (éventuellement important) d'étapes, où chaque étape prend un certain nombre de fichiers en entrée et crée un fichier en sortie.

Une étape peut être «compiler file.cvers file.o» ou «utiliser ldpour lier main.oet file.oentrer program». Si vous interrompez makeavec CtrlC, alors l'étape en cours d'exécution sera terminée, ce qui supprimera (ou devrait supprimer) le fichier de sortie sur lequel il travaillait. Il n'y a généralement pas de "binaires à moitié prêts".

Lorsque vous redémarrez make, il examinera les horodatages de tous les fichiers d'entrée et de sortie et réexécutera les étapes où:

  • un fichier d'entrée a un horodatage plus récent que le fichier de sortie
  • le fichier de sortie n'existe pas

Cela signifie généralement que si une étape prend beaucoup de temps à s'exécuter (c'est rare sur les ordinateurs modernes, mais l' ldétape pour les gros programmes peut facilement prendre plusieurs minutes lorsqu'elle a makeété conçue), puis l'arrêt et le redémarrage makerecommenceront cette étape depuis le début.

La réalité de votre moyenne Makefileest considérablement plus compliquée que la description ci-dessus, mais les fondamentaux sont les mêmes.

Greg Hewgill
la source
8

Ctrl+ Centraîne SIGINTl'envoi de a au processus en cours d'exécution. Ce signal peut être capté par le processus. Dans le code source de make, vous pouvez trouver un piège pour ce signal dans 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()est la fonction de nettoyage de make, voir sa définition ici:

/* 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.  */

Et plus tard dans la fonction que vous voyez, ils seront effectivement supprimés:

status = unlink (f->name);

Conclusion: N'ayez généralement pas peur d'interrompre une compilation avec make. Si ce n'est pas un signal inaccessible ( SIGKILL, SIGSEGV, SIGSTOP), il fera un nettoyage des fichiers intermédiaires.

le chaos
la source
1
SIGSEGVest capturable sur de nombreux Unices.
Chris Down
1

Quand quelque chose s'arrête make(que ce soit ctrl-C, arrêt ou même une commande qui échoue), le travail déjà fait reste. Une fois reformulé, makefait comme toujours: il détermine ce qui reste à faire (car un fichier a changé ou maken'a jamais dû être traité, peu importe) et continue le travail.

La description ci-dessus suppose clairement que les Makefiles pertinents décrivent les dépendances et les commandes à exécuter correctement, donc tout ce qui doit être (re) fait est.

vonbrand
la source