makefile文件是用來幫助編譯和管理C++項目代碼的,須要配合make命令使用。makefile裏也能夠執行shell操做,具有一部分.sh腳本的功能。ios
makefile內容的編寫按照以下規則shell
目標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命令時會報spa
[root@localhost makefiletest]# make makefile:5: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
如下面簡單的C++代碼爲例,說明makefile的具體使用。code
源代碼文件test.cppip
#include <string> #include <iostream> #include<iomanip> int main(int argc, char** argv) { using namespace std; int i =1 ; int j = 2; j += 3; cout << j<<endl; }
makefile文件,文件就是makefilestring
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命令io
[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。
上面兩個規則完成了從源代碼到可執行文件的編譯。test
其實咱們直接執行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文件的生成規則。stream
上面說的是按最原始的寫法,實際makefile的編寫有不少技巧使得編寫量大大減小,
這些均可以大大減小makefile的篇幅。若是打開一個開源C++項目的makefile,會以爲徹底看不懂,就是由於裏面大量使用各類技巧。但即便咱們用最原始辦法也就是第一次編寫麻煩一些,以後維護是很簡單的,由於一個C++項目不會頻繁的大變樣。
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,不然不從新編譯。