Как заставить продолжить компиляцию?

11

Я знаю, что могу в любой момент прервать makeпроцесс без необходимости перекомпилировать все дерево исходников. Как я знаю, makeцель компилируется , только если она еще не скомпилирована или исходный код изменен после последней компиляции.
Но если я прерву make, то наверняка будет один или несколько (в зависимости от уровня параллелизма) наполовину готовых двоичных файлов. Что с ними делать при следующем запуске make? Или это завершает текущую цель, когда я нажимаю Ctrl+, Cчтобы избежать частично скомпилированных двоичных файлов?

psimon
источник
2
В основном вам нужно беспокоиться, только если компьютер неожиданно выключился. Несколько раз моему Ubuntu удавалось зайти в тупик ядра (или что бы то ни было) и оставлять наполовину готовые двоичные файлы, которые заканчивались потерей более двух часов.
Элвин Вонг

Ответы:

12

Проще говоря, вы можете думать о makeналичии (возможно, большого) количества шагов, где каждый шаг принимает в качестве входных данных несколько файлов и создает один файл в качестве выходных.

Шаг может быть «компилировать file.cв file.o» или «использовать ldдля ссылки main.oи file.oв program». Если прервать makeс CtrlC, то шаг в настоящее время выполнения будет прерван , который будет (или должен) удалить выходной файл , он работает на. Обычно там не осталось "полу-готовых двоичных файлов".

При перезапуске makeон будет смотреть на временные метки всех входных и выходных файлов и перезапускать шаги, где:

  • входной файл имеет более новую временную метку, чем выходной файл
  • выходной файл не существует

Как правило, это означает, что если выполнение шага занимает много времени (это редко встречается на современных компьютерах, но ldшаг для больших программ может легко занять много минут, когда он makeбыл разработан), то остановка и перезапуск makeначнут этот шаг с самого начала.

Реальность вашего среднего Makefileзначительно сложнее, чем приведенное выше описание, но основные принципы те же.

Грег Хьюгилл
источник
8

Ctrl+ Cвызывает 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), он выполнит очистку промежуточных файлов.

хаос
источник
1
SIGSEGVможно поймать на многих Unices.
Крис Даун
1

Когда что-то останавливается make(будь то Ctrl-C, завершение работы или даже команда, которая не работает), уже выполненная работа остается. При пересчете makeделает как всегда: он вычисляет, что еще нужно сделать (потому что файл изменился или makeникогда не должен был его обрабатывать, не имеет значения) и продолжает работу.

Вышеприведенное описание явно предполагает, что соответствующие Makefileописания и команды должны выполняться правильно, поэтому все, что нужно (пере) сделать, это.

vonbrand
источник