Я знаю, что могу прервать make
процесс в любое время, не перекомпилируя все исходное дерево снова. Как я знаю, make
компилирует цель, только если она еще не скомпилирована или исходный код был изменен после последней компиляции.
Но если я прерываю make
, наверняка будет один или несколько (в зависимости от уровня параллелизма) полуготовых двоичных файлов. Что он делает с ними при следующем запуске make
? Или он завершает текущую цель, когда я нажимаю Ctrl+ C, чтобы избежать частично скомпилированных двоичных файлов?
решение1
Проще говоря, это можно представить make
как наличие (возможно, большого) количества шагов, где каждый шаг принимает несколько файлов в качестве входных данных и создает один файл в качестве выходных данных.
Шаг может быть "компилировать file.c
в file.o
" или "использовать ld
для компоновки main.o
и file.o
в program
". Если вы прерываете make
с помощью CtrlC, то текущий выполняемый шаг будет завершен, что приведет (или должно) удалить выходной файл, над которым он работал. Обычно не остается никаких "полуготовых двоичных файлов".
При перезапуске make
он проверит временные метки всех входных и выходных файлов и повторно выполнит шаги, где:
- входной файл имеет более новую временную метку, чем выходной файл
- выходной файл не существует
Обычно это означает, что если выполнение шага занимает много времени (на современных компьютерах это случается редко, но ld
для больших программ этот шаг мог легко занять много минут, когда make
он был разработан), то остановка и перезапуск make
запустят этот шаг с самого начала.
Реальность вашего среднего показателя Makefile
значительно сложнее, чем описано выше, но основы те же самые.
решение2
Ctrl+ Cвызывает отправку a SIGINT
в запущенный процесс. Этот сигнал может быть перехвачен процессом. В исходном коде make вы можете найти ловушку для этого сигнала в 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()
является функцией очистки make
, см. ее определение здесь:
/* 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. */
И далее в функции, которую вы видите, они будут фактически удалены:
status = unlink (f->name);
Заключение:
В общем случае не бойтесь прерывать компиляцию с помощью make
. Если это не неперехватываемый сигнал ( SIGKILL, SIGSEGV, SIGSTOP
), он произведет очистку промежуточных файлов.
решение3
Когда что-то останавливается make
(будь то ctrl-C, выключение или даже команда, которая не срабатывает), уже выполненная работа остается. Если перефразировать, то make
делает как всегда: вычисляет, что еще нужно сделать (потому что файл был изменен или make
его так и не удалось обработать, не имеет значения) и продолжает работу.
Приведенное выше описание явно предполагает, что соответствующие Makefile
s описывают зависимости и команды для корректного выполнения, поэтому все, что нужно сделать (переделать), это...