本篇文章我們研究一下 Makefile 的是怎樣工作的?

當我們在執行 make 條命令的時候,make 就會去當前檔案下找要執行的編譯規則,也就是 Makefile 檔案。

我們編寫 Makefile 的時可以使用的檔案的名稱 “GNUmakefile” 、“makefile” 、“Makefile” ,make 執行時回去尋找 Makefile 檔案,找檔案的順序也是這樣的。

我們推薦使用 Makefile(一般在工程中都這麼寫,大寫的會比較的規範)。如果檔案不存在,make 就會給我們報錯,提示:

make:*** 沒有明確目標並且找不到 makefile 停止

Makefile的工作流程

Makefile 的具體工作流程可以透過例子來看一下:建立一個包含有多個原始檔和 Makefile 的目錄檔案,原始檔之間相互關聯。

在 Makefile 中新增下面的程式碼:

====================

main

main

o

test1

o

test2

o

gcc

main

o

test1

o

test2

o

-

o

main

main

o

main

c

test

h

gcc

-

c

main

c

-

o

main

o

test1

o

test1

c

test

h

gcc

-

c

test1

c

-

o

test1

o

test2

o

test2

c

test

h

gcc

-

c

test2

c

-

o

test2

o

====================

在我們編譯專案檔案的時候,預設情況下,make 執行的是 Makefile 中的第一規則(Makefile 中出現的第一個依賴關係),此規則的第一目標稱之為“最終目標”或者是“終極目標”。

在 shell 命令列執行的 make 命令,就可以得到可執行檔案 main 和中間檔案 main。o、test1。o 和 test2。o,main 就是我們要生成的最終檔案。

透過 Makefile 我們可以發現,目標 main“在 Makefile 中是第一個目標,因此它就是 make 的終極目標,當修改過任何 C 檔案後,執行 make 將會重建終極目標 main。

它的具體工作順序是:

當在 shell 提示符下輸入 make 命令以後。 make 讀取當前目錄下的 Makefile 檔案,並將 Makefile 檔案中的第一個目標作為其執行的“終極目標”,開始處理第一個規則(終極目標所在的規則)。在我們的例子中,第一個規則就是目標 ”main“ 所在的規則。

規則描述了 ”main“ 的依賴關係,並定義了連結 ”。o“ 檔案生成目標 ”main“ 的命令;make 在執行這個規則所定義的命令之前,首先處理目標 ”main“ 的所有的依賴檔案(例子中的那些 ”。o“ 檔案)的更新規則(以這些 ”。o“ 檔案為目標的規則)。

對這些 ”。o“ 檔案為目標的規則處理有下列三種情況:

✿ 目標 ”。o“ 檔案不存在,使用其描述規則建立它;

✿ 目標 ”。o“ 檔案存在,目標 ”。o“ 檔案所依賴的 ”。c“ 原始檔 ”。h“ 檔案中的任何一個比目標 ”。o“ 檔案“更新”(在上一次 make 之後被修改)。則根據規則重新編譯生成它;

✿ 目標 ”。o“ 檔案存在,目標 ”。o“ 檔案比它的任何一個依賴檔案(”。c“ 原始檔、”。h“ 檔案)“更新”(它的依賴檔案在上一次 make 之後沒有被修改),則什麼也不做。

透過上面的更新規則我們可以瞭解到中間檔案的作用,也就是編譯時生成的 ”。o“ 檔案。作用是檢查某個原始檔是不是進行過修改,最終目標檔案是不是需要重建。

我們執行 make 命令時,只有修改過的原始檔或者是不存在的目標檔案會進行重建,而那些沒有改變的檔案不用重新編譯,這樣在很大程度上節省時間,提高程式設計效率。小的工程專案可能體會不到,專案工程檔案越大,效果才越明顯。

當然 make 命令能否順利的執行,還在於我們是否制定了正確的的依賴規則,當前目錄下是不是存在需要的依賴檔案,只要任意一點不滿足,我們在執行 make 的時候就會出錯。所以完成一個正確的 Makefile 不是一件簡單的事情。

清除工作目錄中的過程檔案

我們在使用的時候會產生中間檔案會讓整個檔案看起來很亂,所以在編寫 Makefile 檔案的時候會在末尾加上這樣的規則語句:

PHONY

clean

clean

rm

-

rf

*

o

test

其中 ”*。o“ 是執行過程中產生的中間檔案,”test“ 是最終生成的執行檔案。我們可以看到 clean 是獨立的,它只是一個偽目標(在《Makefile偽目標》的章節中詳細介紹),不是具體的檔案。不會與第一個目標檔案相關聯,所以我們在執行 make 的時候也不會執行下面的命令。

在shell 中執行 ”make clean“ 命令,編譯時的中間檔案和生成的最終目標檔案都會被清除,方便我們下次的使用。

【Linux程式設計】Makefile 的工作流程!

不管你是轉行也好,初學也罷,進階也可,如果你想學程式設計,進階程式設計師~

【值得關注】我的

程式設計學習交流:

全棧程式設計師正在等你加入~

【Linux程式設計】Makefile 的工作流程!