深入學習Make命令和Makefile(上) 3

2021-06-21 16:22:07 字數 2757 閱讀 4328



五、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結尾的檔案,即把原始檔編譯成目標程式,但是...