前言:
大家在Windows上使用VS構建C/C++程序時,不需要自己編輯略顯晦澀的Makefile文件,而對於初學者而言, 他們甚至沒意識到它的存在。VS是自動生成Makefile文件, 並構建工程項目的。不可否認Visual Studio做為一款全能的IDE,它幫開發者做了很多工作,也降低了C/C++的門檻,意義非常的重大。
但作為進階的C/C++開發者, 你是有必須了解底層編譯和鏈接原理的。 讓我們來梳理下C/C++的編譯鏈接過程,並回顧Makefile的編寫規則,最后讓我們來嘗試實現自動構建工程Makefile文件的機制。本文側重講解C/C++的編譯過程和Makefile的規則,后文講述如何實現Makefile的生成器。
編譯C/C++程序
C/C++程序的生成, 分為如下幾個步驟
1). 預處理: 引入頭文件,解析並展開宏定義
2). 編譯: 簡單一點就是把源代碼轉化為匯編碼(機器指令)
3). 鏈接: 組裝各個子模塊和相應的庫,並生成最終的可執行程序

評注: 參數-E用於生成預處理后的c/c++文件, 參數-c用於生成編譯后的二進制文件,參數-o則只是用於制定某個階段的產出物名稱
Makefile的基礎規則
基本規則很簡單:
<target> : <prerequisites> <command>
評注: <target>是目標名稱, <prerequisites>是依賴的列表項, <command>則是對應的執行命令
當然有些注意項:
1). Makefile第一項執行規則為默認的最終目標
2). 命令必須"\t"作為開頭
Makefile常見的宏定義:
$^ 依賴項列表 $@ 目標對象 $< 依賴列表中的第一個對象
Makefile的變量定義和使用, 如下所示:
CC = g++ CFLAG = -g -WALL app: main.cpp $(CC) $(CFLAG) -o $@ $^
評注:變量CC/CFLAG展示了Makefile的定義和引用語法
偽目標對象的引入, 對於make clean特別有用
.PHONY : clean clean: -rm $(OBJECTS)
其實PHONY的引入, 是針對文件系統中,剛好有名為"clean"文件的特殊情形。各位看官, 你還記得大明湖畔的夏雨荷嗎? 就是這種感覺
Makefile的小實戰
對於如下工程:

include包含工程的頭文件,src包含工程的C/C++文件
其具體的Makefile文件,可以編輯如下所示:
CC = g++ CFLAG = -g -Wall OBJECTS := $(wildcard *.o) app : app.o cache.o g++ $(CFLAG) -o $@ $^ app.o : src/app.cpp include/cache.h g++ -c -o $@ src/app.cpp -Iinclude cache.o : src/cache.cpp include/cache.h g++ -c -o $@ src/cache.cpp -Iinclude .PHONY : clean clean: -rm $(OBJECTS)
這個實戰項目就算完成了, Makefile文件具備了它所需要的功能:生成/清理。
挑戰
實戰的工程還是比較小,手動維護Makefile還是相對簡單的,那如果工程有上百個頭文件/C文件呢?還有相關的依賴庫?是不是很麻煩
如果說,增量去編寫還能接受的話,那么時間一長,回過頭來回顧,或者移交給他人,都是件麻煩的事, 是不是?
那能不能自動生成和維護該Makefile文件,它的核心思想是什么?又該如何去實現? 請期待下文......
