Як продовжувати компіляцію?


11

Я знаю, що я можу перервати makeпроцес у будь-який час без необхідності повторного перекомпіляції всього вихідного дерева. Як я знаю, makeціль компілює лише те, що вона ще не скомпільована, або вихідний код змінено після останньої компіляції.
Але якщо я перерву make, напевно знайдеться один або кілька (залежно від рівня сумісності) напів готових бінарних файлів. Що це робиться з ними наступного разу, коли я біжу make? Або закінчується поточна ціль, коли я натискаю Ctrl+, Cщоб уникнути частково складених двійкових файлів?


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надсилання a в процес, що працює. Цей сигнал може вловлювати процес. У вихідному коді 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описують залежності та команди для правильного виконання, тому все, що потрібно (повторно) зробити, - це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.