¿Cómo hace que continúe la compilación?

11

Sé que puedo interrumpir un makeproceso en cualquier momento sin tener que volver a compilar todo el árbol de origen. Como sé, makesolo compila un objetivo si aún no está compilado o si el código fuente se modifica después de la última compilación.
Pero si lo interrumpo make, seguramente habrá uno o más binarios a medias (dependiendo del nivel de concurrencia). ¿Qué hace con ellos la próxima vez que corro make? ¿O termina el objetivo actual cuando presiono Ctrl+ Cpara evitar binarios parcialmente compilados?

psimon
fuente
2
En general, solo debe preocuparse si la computadora se apaga inesperadamente. Unas pocas veces mi Ubuntu logró entrar en un punto muerto del kernel (o lo que sea) y dejó binarios medio listos, que terminaron perdiendo más de dos horas.
Alvin Wong

Respuestas:

12

En términos simples, puede pensar makeque tiene un número (posiblemente grande) de pasos, donde cada paso toma una cantidad de archivos como entrada y crea un archivo como salida.

Un paso podría ser "compilar file.ca file.o" o "usar ldpara vincular main.oy file.oen program". Si se interrumpe makecon CtrlC, entonces la etapa de ejecución actual se dará por terminado que (o debe) quitar el archivo de salida que estaba trabajando. Por lo general, no quedan "binarios a medio preparar".

Cuando reinicie make, verá las marcas de tiempo de todos los archivos de entrada y salida y volverá a ejecutar los pasos donde:

  • un archivo de entrada tiene una marca de tiempo más nueva que el archivo de salida
  • el archivo de salida no existe

Esto generalmente significa que si un paso tarda mucho en ejecutarse (es raro en las computadoras modernas, pero el ldpaso para programas grandes podría tomar fácilmente muchos minutos cuando makese diseñó), entonces detener y reiniciar makecomenzará ese paso desde el principio.

La realidad de su promedio Makefilees considerablemente más complicada que la descripción anterior, pero los fundamentos son los mismos.

Greg Hewgill
fuente
8

Ctrl+ Chace SIGINTque se envíe a al proceso en ejecución. Esta señal puede ser captada por el proceso. En el código fuente de make, puede encontrar una trampa para esta señal en 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()es la función de limpieza de make, vea su definición aquí:

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

Y más adelante en la función que ve, se eliminarán efectivamente:

status = unlink (f->name);

Conclusión: en general, no tengas miedo de interrumpir una compilación con make. Si no es una señal que no se puede capturar ( SIGKILL, SIGSEGV, SIGSTOP), limpiará los archivos intermedios.

caos
fuente
1
SIGSEGVes atrapable en muchos Unices.
Chris Down
1

Cuando algo se detiene make(ya sea ctrl-C, apagado o incluso un comando que falla), el trabajo ya realizado permanece. Cuando se reinicia, lo makehace como siempre: se da cuenta de lo que aún hay que hacer (porque un archivo cambiado o makenunca tuvo que procesarse no importa) y continúa con el trabajo.

La descripción anterior supone claramente que los Makefiles relevantes describen las dependencias y comandos para ejecutar correctamente, por lo que todo lo que se necesita (re) hacer es.

vonbrand
fuente