make和Makefile中的規則和變數

2021-07-17 05:40:42 字數 4241 閱讀 9375

make機制的執行環境需要乙個命令列程式make和乙個文字檔案makefile。

make命令執行後有3個退出碼:

make的使用格式是:

make [options] [target] ...

options為make工具的引數選項,target為makefile中指定的目標。

make

工具的引數選項

選項含義

-f filename

顯式地指定檔案作為makefile

-c dirname

指定make在開始執行後的工作目錄為dirname -e

不允許在makefile中替換環境變數的賦值-k

執行命令出錯時,放棄當前目標,繼續維護其他目標-n

按實際執行時的執行順序模擬執行命令(包括用@開頭的命令),沒有實際執行效果,僅僅用於顯示執行過程-p

顯示makefile中所有的變數和內部規則-r

忽略內部規則-s

執行但不顯示命令-s

如果執行命令出錯就退出-t

修改每個目標檔案的建立日期-i

忽略執行make中執行命令的錯誤-v

顯示make的版本號

make操作管理makefile檔案的規則

在makefile中,目標名稱的指定通常有以下慣例:

makefile

的書寫規則

makefile的書寫規則包含兩個部分,乙個是依賴關係,乙個是生成目標的方法。

makefile中只有乙個最終目標,第一條規則中的第乙個目標將被確立為最終的目標。

makefile裡主要包含了5方面的內容:顯式規則、隱式規則、變數定義、檔案指示和注釋。

makefile

的基本語法規則

makefile

的語法格式如下:

targets : prerequisites

command

...或者是:

targets : prerequisites ; command

command

...對於makefile檔案:

all : main.c foo1.c foo2.c foo3.c

gcc main.c foo1.c foo2.c foo3.c -o all

all是makefile

時最終目標,main.c,foo1.c,foo2.c,foo3.c

是目標所依賴的原始檔,而只有乙個命令「gcc main.c foo1.c foo2.c foo3.c -o all」

是生成目標的方法:

檔案的依賴的關係:可執行檔案all

依賴於main.c,foo1.c,foo2.c,foo3.c

檔案,如果main.c,foo1.c,foo2.c,foo3.c

中的任何乙個的修改日期比all

檔案日期新,或者是all

不存在,那麼依賴關係發生。

如何生成(或更新)all

檔案。那個gcc

命令,說明了all

這個檔案生成目標的方法。

在規則中使用萬用字元

make支援3種萬用字元:「*」,「?」,「[...]」。

「~」字元在檔名中有特殊用途:比如「~/test」表示當前使用者的$home目錄下的test目錄;「~zhangfan/test」則表示使用者zhangfan的宿主目錄下的test目錄。

萬用字元代替了一系列的檔案,如」*.c」表示了所有字尾名為.c的檔案。如果檔名中含有萬用字元,如「*」,那麼可以用轉義字元斜槓」\」,如「\*」來表示真實的」*「字元,而不是任意長度的字串。

可以使用乙個特殊的標記「.phony」來顯式地指明乙個目標是偽目標,向make說明,不管是否有這個檔案,這個目標都是偽目標:

.phony : clean

只要有這個宣告,不管是否有「clean」檔案,要執行「clean」這個目標,只要在命令提示符下輸入命令「make clean」即可。於是整個過程可以這樣寫,例如:

.phony : clean

clean :

rm all main.o kbd.o command.o \

insert.o search.o files.o

自動生成依賴關係

可以使用gnu的c/c++編譯器的「-mm」引數選項,使其自動尋找原始檔中包含的標頭檔案,並生成乙個依賴關係。例如main.c檔案中有defs.h標頭檔案,那麼:

gcc -mm main.c

其輸出是:

main.o : main.c defs.h

變數變數在宣告時需要給予初值,而在使用時,需要在變數名前加上「$」符號,但最好用小括號「()」或是花括號」{}」把變數給引用起來。如果使用真實的」$」字元,那麼需要用」$$」來表示。

下面makefile等同:

objects=program.o foo.o utils.o

program:$(objects)

cc -o program $(objects)

$(objects):defs.h

等同於:

objects=program.o foo.o utils.o

program:program.o foo.o utils.o

cc -o program program.o foo.o utils.o

program.o foo.o utils.o:defs.h

賦值變數

1、使用「:=」操作符,使得前面的變數不能使用後面的變數,只能使用前面已定義好了的變數。

2、使用」?=」操作符:例如foo ?= bar

如果foo沒有被定義過,那麼變數foo的值就是「bar」,否則此語句什麼也不做,這段**等同於:

ifeq($(origin foo),undefined)

foo=bar;

endif

3、使用「+=」操作符,可以追加值,

objects=main.o foo.o bar.o

objects+=another.o

等同於objects=main.o foo.o bar.o

objects:=$(objects) another.o

define關鍵字

使用define定義的命令變數中沒有以「tab」鍵開頭。

define two-lines

echo foo

echo $(bar)

endef

這段**將變數two-lines定義為兩條命令echo foo和echo $(bar)。

override指示符

有的變數時通過make的命令列引數進行設定的,那麼makefile將忽略這個變數的賦值。如果想在makefile中設定這類引數的值,那麼可以使用「override」指示符。

override =

override :=

override +=

在define關鍵字中也同樣可以使用override指示符:

override define foo

barendef

目標變數和模式變數

1、目標變數 :

:override

為目標序列,可以是各種賦值表示式,如」=」、」:=「,」+=「,」?=」。第二個語法針對於make命令列引數帶入的變數,或是系統環境變數。

prog : cflags=-g

prog : prog.o foo.o bar.o

$(cc) $(cflags) prog.o foo.o bar.o

prog.o : prog.c

$(cc) $(cflags) prog.c

foo.o : foo.c

$(cc) $(cflags) foo.c

bar.o : bar.c

$(cc) $(cflags) bar.c

等同於prog : prog.c foo.c bar.o

gcc -g prog.o foo.o bar.o

prog.o : prog.c

gcc -g prog.c

foo.o : foo.c

gcc -g foo.c

bar.o : bar.c

gcc -g bar.c

2、模式變數

可以給定一種「模式」,把變數定義在符合這個模式的所有目標中。:

:override

是模式序列,可以是多種模式,override同樣是針對系統環境傳入的變數或是make命令列指定的變數。

make的模式變數一般是至少含有乙個「%」的,所以,可以以如下方式給所有以」.o」結尾的目標定義目標模式變數:

%.o : cflags=-o

make 和 makefile 的關係

要先總結make和makefile,就需要先了解下面這個過程 預編譯 也叫預處理,進行一些文字替換工作,比如將 define定義的內容,在 中進行替換 編譯 將預處理得到的 進行詞法分析 語法分析 中間 如果是在windows下,中間 就是.obj檔案 在linux系統下,中間 就是.o檔案 彙編 ...

(一)make之make和makefile初識

1.1 make 和makefile 1.1.1 make make 是乙個應用程式 1.1.2 makefile makefile是乙個描述檔案 1.1.3 makefile本質 makefile實際就是乙個指令碼程式,類似於shell指令碼。由於 塊中沒有make的,所以用bash來代替make...

make命令和makefile檔案

make命令是用於程式編譯的工具,當需要通過多個輸入檔案來生成輸出檔案時,可以利用它來完成。make命令的一些可選引數 b 無條件編譯所有目標 c dir 讀取makefile之前切換到指定的目錄dir f 告訴make命令將哪個檔案作為makefile檔案 n 讓make命令輸出將要執行的操作步驟...