五、makefile中的規則
除了指明目標和模組之間的依賴關係之外,makefile還要規定相應的規則來描述如何生成目標,或者說使用哪些命令來根據依賴模組產生目標。就上例而言,當make程式發現需要重新構建f1.o的時候,該使用哪些命令來完成呢?很遺憾,到目前為止,雖然make知道哪些檔案需要更新,但是卻不知道如何進行更新,因為我們還沒有告訴它相應的命令。
當然,我們可以使用命令gcc -c f1.c來完成,不過如果我們需要規定乙個include目錄,或者為將來的除錯準備符號資訊的話,該怎麼辦呢?所有這些,都需要在makefile中用相應規則顯式地指出。
實際上,makefile是以相關行為基本單位的,相關行用來描述目標、模組及規則(即命令列)三者之間的關係。乙個相關行格式通常為:冒號左邊是目標(模組)名;冒號右邊是目標所依賴的模組名;緊跟著的規則(即命令列)是由依賴模組產生目標所使用的命令。相關行的格式為:
目標:[依賴模組][;命令]
習慣上寫成多行形式,如下所示:
目標:[依賴模組]
命令命令
需要注意的是,如果相關行寫成一行,「命令」之前用分號「;」隔開,如果分成多行書寫的話,後續的行務必以tab字元為先導。對於makefile而言,空格字元和tab字元是不同的。所有規則所在的行必須以tab鍵開頭,而不是空格鍵。初學者一定對此保持警惕,因為這是新手最容易疏忽的地方,因為幾個空格鍵跟乙個tab鍵在肉眼是看不出區別的,但make命令卻能明察秋毫。
此外,如果在makefile檔案中的行尾加上空格鍵的話,也會導致make命令執行失敗。所以,大家一定要小心了,免得耽誤許多時間。
六、makefile檔案舉例
main: main.o f1.o f2.o
gcc -o main main.o f1.o f2.o
main.o: main.c def1.h
gcc -c main.c
f1.o: f1.c def1.h def2.h
gcc -c f1.c
f2.o: f2.c def2.h def3.h
gcc -c f2.c
注意,由於我們這裡沒有使用預設名makefile 或者makefile ,所以一定要在make命令列中加上-f選項。如果在沒有任何原始碼的目錄下執行命令「make -f mymakefile1」的話,將收到下面的訊息:
make: *** no rule to make target 『main.c』, needed by 『main.o』. stop.
make命令將makefile中的第乙個目標即main作為要構建的檔案,所以它會尋找構建該檔案所需要的其他模組,並判斷出必須使用乙個稱為main.c的檔案。因為迄今尚未建立該檔案,而makefile又不知道如何建立它,所以只好報告錯誤。好了,現在建立這個原始檔,為簡單起見,我們讓標頭檔案為空,建立標頭檔案的具體命令如下:
$ touch def1.h
$ touch def2.h
$ touch def3.h
我們將main函式放在main.c檔案中,讓它呼叫function2和function3,但將這兩個函式的定義放在另外兩個原始檔中。由於這些原始檔含有#include命令,所以它們肯定依賴於所包含的標頭檔案。如下所示:
/* main.c */
#include
#include 「def1.h」
extern void function2();
extern void function3();
int main()
/* f1.c */
#include 「def1.h」
#include 「def2.h」
void function2()
/* f2.c */
#include 「def2.h」
#include 「def3.h」
void function3()
建好源**後,再次執行make程式,看看情況如何:
$ make -f mymakefile1
gcc -c main.c
gcc -c f1.c
gcc -c f2.c
gcc -o main main.o f1.o f2.o
$好了,這次順利通過了。這說明make命令已經正確處理了makefile描述的依賴關係,並確定出了需要建立哪些檔案,以及它們的建立順序。雖然我們在makefile 中首先列出的是如何建立main,但是make還是能夠正確的判斷出這些檔案的處理順序,並按相應的順序呼叫規則部分規定的相應命令來建立這些檔案。當這些命令執行時,make程式會按照執**況來顯示這些命令。
如今,我們對def2.h加以變動,來看看makefile能否對此作出相應的回應:
$ touch def2.h
$ make -f mymakefile1
gcc -c f1.c
gcc -c f2.c
gcc -o main main.o f1.o f2.o
$這說明,當make命令讀取makefile 後,只對受def2.h的變化的影響的模組進行了必要的更新,注意它的更新順序,它先編譯了c程式,最後連線生產了可執行檔案。現在,讓我們來看看刪除目標檔案後會發生什麼情況,先執行刪除,命令如下:
$ rm f1.o
然後執行make命令,如下所示:
$ make -f mymakefile1
gcc -c f1.c
gcc -o main main.o f1.o f2.o$
很好,make的行為讓我們非常滿意。
深入學習Make命令和Makefile(上)(1)
make是linux下的一款程式自動維護工具,配合makefile的使用,就能夠根據程式中模組的修改情況,自動判斷應該對那些模組重新編譯,從而保證軟體是由最新的模組構成。本文分為上下兩部分,我們將緊緊圍繞make在軟體開發中的應用展開詳細的介紹。深入學習make命令和makefile 下 一 都是原...
深入學習Make命令和Makefile(下) 1
一 構建多個目標 有時候,我們想要在乙個makefile中生成多個單獨的目標檔案,或者將多個命令放在一起,比如,在下面的示例mymakefile3中我們將新增乙個clean 選項來清除不需要的目標檔案,然後用install選項將生成的應用程式移動到另乙個目錄中去。這個makefile跟前面的myma...
深入學習Make命令和Makefile(下) 3
三 字尾規則 前面我們已經看到,有些內部規則會根據檔案的字尾 相當於windows系統中的副檔名 來採取相應的處理。換句話說,這樣當make見到帶有一種字尾的檔案時,就知道使用哪些規則來建立乙個帶有另外一種字尾的檔案,最常見的是用以.c結尾的檔案來建立以.o結尾的檔案,即把原始檔編譯成目標程式,但是...