makefile檔案是用來幫助編譯和管理C++專案程式碼的,需要配合make命令使用。makefile裡也可以執行shell操作,具備一部分。sh指令碼的功能。

makefile格式

makefile內容的編寫按照如下規則

目標1:依賴1

命令1

目標2:依賴2

命令2

目標3:依賴3

命令3

……………………。

目標N:依賴N

命令N

命令可以是任意的shell語句。多數情況下,命令都是起到了從依賴生成目標的功能。例如從。cpp檔案生成。o檔案,那麼命令一定包括g++和一些編譯引數的完整的編譯命令。

目標1 2 3可以是巢狀依賴的,如果依賴1裡包含目標2 目標3,那就是一種巢狀的依賴。也可以是獨立的,例如目標1 2 3就是三個獨立的可執行檔案,或者三個動態庫,那麼他們之間是可以完全沒有依賴關係的,寫在一個makefile檔案裡只是便於統一管理。

命令前要以一個tab開頭 。如果使用空格代替tab,執行make命令時會報

[root@localhost makefiletest]# make

makefile:5: *** missing separator (did you mean TAB instead of 8 spaces?)。 Stop。

舉個例子

以下面簡單的C++程式碼為例,說明makefile的具體使用。

原始碼檔案test。cpp

#include

#include

#include

int main(int argc, char** argv)

{

using namespace std;

int i =1 ;

int j = 2;

j += 3;

cout << j<

}

makefile檔案,檔案就是makefile

CC=g++

all = test。o

test: $(all)

$(CC) -o test $(all)

test。o: 。/test。cpp

$(CC) -c test。cpp

clear:

rm -f *。o test

執行make命令

[root@localhost makefiletest]# make

g++ -c test。cpp

g++ -o test test。o

[root@localhost makefiletest]# ls -lrt

total 24

-rw-r——r——。 1 root root 196 Aug 6 11:00 test。cpp

-rw-r——r——。 1 root root 120 Aug 6 11:04 makefile

-rw-r——r——。 1 root root 2328 Aug 6 11:04 test。o

-rwxr-xr-x。 1 root root 8840 Aug 6 11:04 test

正確生成了test和test。o

例子講解

makefile中的“目標1”test是個可執行檔案,也是最終我們需要的東西。test依賴

(all)這個變數,檔案開頭定義了all = test.o,所以test依賴的是test.o,生成test的命令是

(CC) -o test $(all),進行變數替換後就是g++ -o test test。o,是一個我們熟知最基礎的編譯命令。

同理,“目標2”test。o依賴的是test。cpp,生成目標的命令是g++ -c test。cpp。

上面兩個規則完成了從原始碼到可執行檔案的編譯。

大型工程必須用makefile

其實我們直接執行g++ -o test test。cpp就可以生成test了,但這種直接敲命令只適用於程式碼檔案很少的情況。

即使專案只有5個檔案,每次程式碼更新都要敲5個編譯命令也是很麻煩的。我們只要編寫一次makefile,之後每次程式碼更新,或者程式碼檔案有增減,都只需要修改makefile對應的一小部分內容,然後執行make就行了。 例如test依賴是100個。o檔案,在上面的makefile中我們只要寫一次all = test。o test1。o test2。o 。。。。。 test99。o,就把目標test的生成規則表達清楚了。當然下面要寫上100個。o檔案的生成規則。

上面說的是按最原始的寫法,實際makefile的編寫有很多技巧使得編寫量大大減少,

編譯命令的各種引數選項統一都寫在變數中

模式匹配

特殊符號程式碼依賴集

目標集

shell指令在makefile裡完成自動查詢生成所有檔名,然後替換。cpp為。o的玩法

這些都可以大道減少makefile的篇幅。如果開啟一個開源C++專案的makefile,會覺得完全看不懂,就是因為裡面大量使用各種技巧。但即使我們用最原始辦法也就是第一次編寫麻煩一些,之後維護是很簡單的,因為一個C++專案不會頻繁的大變樣。

makefile檔名

make預設支援makefile和Makefile兩種檔名,所以我們直接執行make等價於執行make Makefile。如果我們寫make規則的檔案叫test20200806,需要執行的命令是make -f test20200806。

並行編譯

並行make的命令是make -j。可以加快工程編譯速度,對於大規模工程適用。

自動推導

make會自動推導各個目標的依賴關係,按照依賴關係的順序生成目標檔案。

偽目標

本文makefile裡的“目標3”clear是個偽目標,偽目標後面無檔案依賴,make不自動找檔案依賴,無法執行後面的命令。要執行偽目標,就要make+為目標名。執行make clear,會執行下面的rm命令,這種命令用來清理專案之前編譯的。o等檔案,在需要徹底重新編譯專案時都會執行這個命令。

[root@bogon makefiletest]# make clear

rm -f *。o test

如果不執行make clear清理之前的。o檔案,make會比較。o和。cpp誰更新,如果依賴檔案cpp更新,重新編譯這個。o,否則不重新編譯。