W jaki sposób kompilacja kontynuuje kompilację?


11

Wiem, że mogę przerwać makeproces w dowolnym momencie bez konieczności ponownej kompilacji całego drzewa źródeł. Jak wiem, makekompiluje cel tylko wtedy, gdy nie został jeszcze skompilowany lub kod źródłowy został zmodyfikowany po ostatniej kompilacji.
Ale jeśli przeszkodzę make, na pewno będzie jeden lub więcej (w zależności od poziomu współbieżności) w połowie gotowych plików binarnych. Co to robi z nimi przy następnym uruchomieniu make? Czy też kończy bieżący cel, gdy naciskam Ctrl+, Caby uniknąć częściowo skompilowanych plików binarnych?


2
Przeważnie musisz się tylko martwić, jeśli komputer niespodziewanie się wyłączy. Kilka razy moje Ubuntu udało się wejść w impas jądra (lub cokolwiek to jest) i pozostawić w połowie gotowe pliki binarne, co skończyło się marnowaniem ponad dwóch godzin.
Alvin Wong,

Odpowiedzi:


12

Mówiąc prościej, można pomyśleć makeo (prawdopodobnie dużej) liczbie kroków, przy czym każdy krok przyjmuje liczbę plików jako dane wejściowe i tworzy jeden plik jako dane wyjściowe.

Krokiem może być „skompiluj file.cdo file.o” lub „użyj lddo połączenia main.oi file.odo program”. Jeśli przerywa makesię CtrlC, a następnie krok aktualnie wykonywany zostanie zakończony, które będą (lub powinien) usunąć plik wyjściowy został pracuje. Zwykle nie ma po nich żadnych „w połowie gotowych plików binarnych”.

Po ponownym uruchomieniu make, spojrzy na znaczniki czasu wszystkich plików wejściowych i wyjściowych i uruchom ponownie kroki, w których:

  • plik wejściowy ma nowszą sygnaturę czasową niż plik wyjściowy
  • plik wyjściowy nie istnieje

Ogólnie oznacza to, że jeśli wykonanie kroku zajmuje dużo czasu (jest to rzadkie na nowoczesnych komputerach, ale ldetap dla dużych programów może z łatwością zająć wiele minut, jeśli makezostał zaprojektowany), wówczas zatrzymanie i ponowne uruchomienie makerozpocznie ten krok od początku.

Rzeczywistość średniej Makefilejest znacznie bardziej skomplikowana niż powyższy opis, ale podstawy są takie same.


8

Ctrl+ Cpowoduje SIGINTwysłanie a do uruchomionego procesu. Ten sygnał może zostać przechwycony przez proces. W kodzie źródłowym make można znaleźć pułapkę dla tego sygnału w 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()jest funkcją czyszczenia make, zobacz jej definicję tutaj:

/* 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.  */

Później w funkcji, którą zobaczysz, zostaną skutecznie usunięte:

status = unlink (f->name);

Wniosek: ogólnie nie bój się przerywać kompilacji make. Jeśli nie jest to sygnał nie do złapania ( SIGKILL, SIGSEGV, SIGSTOP), wyczyści pliki pośrednie.


1
SIGSEGVjest możliwe do złapania na wielu Unikach.
Chris Down,

1

Gdy coś się zatrzymuje make(ctrl-C, zamknięcie, a nawet polecenie, które się nie powiedzie), praca już wykonana zostaje. Po ponownym utworzeniu makerobi jak zawsze: sprawdza, co jeszcze należy zrobić (ponieważ plik został zmieniony lub makenigdy nie został przetworzony, nie ma znaczenia) i kontynuuje pracę.

Powyższy opis wyraźnie zakłada, że ​​odpowiednie Makefiles opisują zależności i polecenia do prawidłowego wykonania, więc wszystko, co należy (ponownie) wykonać.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.