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

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

Я знаю, что могу прервать 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его так и не удалось обработать, не имеет значения) и продолжает работу.

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

Связанный контент