make如何繼續編譯?

make如何繼續編譯?

我知道我可以make隨時中斷進程,而不必再次重新編譯整個原始碼樹。據我所知,make只有在尚未編譯的情況下才編譯目標,或者在上次編譯後修改了原始碼。
但如果我中斷make,肯定會有一個或多個(取決於並發等級)半就緒的二進位檔案。下次我跑步時它們會做什麼make?或者當我按Ctrl+C以避免部分編譯的二進位檔案時它是否完成當前目標?

答案1

簡單來說,您可以將其視為make具有(可能很大)數量的步驟,其中每個步驟都採用多個文件作為輸入並創建一個文件作為輸出。

步驟可能是“編譯file.c到”file.o或“使用ld連結main.o到”。如果您使用中斷,則當前執行的步驟將終止,這將(或應該)刪除它正在處理的輸出檔案。通常不會留下任何“半就緒的二進位”。file.oprogrammakeCtrlC

當您重新啟動時make,它將查看所有輸入和輸出檔案的時間戳記並重新執行以下步驟:

  • 輸入檔的時間戳比輸出檔更新
  • 輸出文件不存在

這通常意味著,如果一個步驟需要很長時間才能運行(這在現代電腦上很少見,但大型程式的步驟在設計ld時很容易花費很多分鐘),那麼停止並重新啟動將從頭開始該步驟。makemake

平均值的實際情況Makefile比上述描述要複雜得多,但基本原理是相同的。

答案2

Ctrl+C導致 aSIGINT被傳送到正在執行的進程。此訊號可以被進程捕獲。在 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描述了正確執行的依賴關係和命令,所以所有需要(重新)製作的都是。

相關內容