Sé que puedo interrumpir un make
proceso en cualquier momento sin tener que volver a compilar todo el árbol fuente. Como sé, make
solo compila un destino si aún no está compilado o si el código fuente se modifica después de la última compilación.
Pero si interrumpo make
, seguramente habrá uno o más (dependiendo del nivel de concurrencia) binarios medio listos. ¿Qué hace con ellos la próxima vez que corro make
? ¿O finaliza el objetivo actual cuando presiono Ctrl+ Cpara evitar archivos binarios parcialmente compilados?
Respuesta1
En términos simples, puede pensar make
que tiene una cantidad (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.c
en file.o
" o "usar ld
para vincular main.o
y file.o
en program
". Si interrumpe make
con CtrlC, el paso que se está ejecutando actualmente finalizará, lo que eliminará (o debería) eliminar el archivo de salida en el que estaba trabajando. Por lo general, no quedan "binarios a medio preparar".
Cuando reinicie make
, mirará 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 reciente que el archivo de salida
- el archivo de salida no existe
Esto generalmente significa que si un paso tarda mucho tiempo en ejecutarse (es poco común en las computadoras modernas, pero el ld
paso para programas grandes fácilmente podría tomar muchos minutos cuando make
fue diseñado), al detenerlo y reiniciarlo, make
se iniciará ese paso desde el principio.
La realidad de su promedio Makefile
es considerablemente más complicada que la descripción anterior, pero los fundamentos son los mismos.
Respuesta2
Ctrl+ Chace que SIGINT
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 puedes 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 ves, se eliminarán efectivamente:
status = unlink (f->name);
Conclusión:
Generalmente no tengas miedo de interrumpir una compilación con make
. Si no es una señal imposible de detectar ( SIGKILL, SIGSEGV, SIGSTOP
), realizará una limpieza de los archivos intermedios.
Respuesta3
Cuando algo se detiene make
(ya sea Ctrl-C, apagado o incluso un comando que falla), el trabajo ya realizado permanece. Cuando se reformula, make
hace lo mismo de siempre: descubre lo que aún queda por hacer ( make
no importa porque un archivo cambió o nunca llegó a procesarse) y continúa con el trabajo.
La descripción anterior supone claramente que los Makefile
s relevantes describen las dependencias y los comandos para ejecutar correctamente, por lo que todo lo que se necesita (re)hacer es.