天天看點

Makefile的工作流程(三)

簡單了解一下 Makefile 書寫規則之後,再來深入研究一下 Makefile 的是怎樣工作的?當我們在執行 make 條指令的時候,make 就會去目前檔案下找要執行的編譯規則,也就是 Makefile 檔案。我們編寫 Makefile 的時可以使用的檔案的名稱 "GNUmakefile" 、"makefile" 、"Makefile" ,make 執行時回去尋找 Makefile 檔案,找檔案的順序也是這樣的。

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

make:*** 沒有明确目标并且找不到 makefile。停止

Makefile的工流程

Makefile 的具體工作流程可以通過例子來看一下:建立一個包含有多個源檔案和 Makefile 的目錄檔案,源檔案之間互相關聯。在 Makefile 中添加下面的代碼:

1. main:main.o test1.o test2.o
2. gcc main.o test1.o test2.o -o main
3. main.o:main.c test.h
4. gcc -c main.c -o main.o
5. test1.o:test1.c test.h
6. gcc -c test1.c -o test1.o
7. test2.o:test2.c test.h
8. 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 檔案的時候會在末尾加上這樣的規則語句:

1. .PHONY:clean
2. clean:
3. rm -rf *.o test      
salman:salman.c
  gcc -o salman salman.c
clean:
  rm -rf *.o salman      

繼續閱讀