下面是定義變量的一般方法:
VARNAME=some_text
[...]
把變量用括號起來,并在前面加上"$"符號,就可以引用變量的值:
$(VARNAME)
變量一般都在makefile的頭部定義,并且,按照慣例,所有的makefile變量都應(yīng)該大寫.
在makefile中使用變量
OBJS
= howdy.o helper.o
HDRS = helper.h
howdy: $(OBJS) $(HDRS)
gcc $(OBJS) -o howdy
helper.o: helper.c $(HDRS)
gcc -c
helper.c
howdy.o: howdy.c
gcc -c howdy.c
hello: hello.c
gcc
hello.c -o hello
all: howdy hello
clean:
rm howdy hello
*.o
make使用兩種變量:遞歸展開變量和簡單展開變量.遞歸展開變量在引用時(shí)逐層展開,即如果在展開式中包含了對其他變量的引用,則這些變量也將被展開,直到?jīng)]有需要展開的變量為止,這就是所謂的遞歸展開.
考慮下面的變量定義:
CC
= gcc
CC = $(CC)
-o
CC在被引用時(shí)遞歸展開,從而陷入一個(gè)無限循環(huán)中:CC將展開為$(CC)的值,從而永遠(yuǎn)也讀不到-o選項(xiàng).
為了避免這個(gè)問題,可以使用簡單展開變量.與遞歸展開變量在引用時(shí)展開不同,簡單展開變量在定義處展開,并且只展開一次,從而取消了變量的嵌套引用.在定義時(shí),其語法與遞歸展開變量有細(xì)微的不同:
CC
:= gcc -o
CC += -O2
第一個(gè)定義使用":="設(shè)置CC的值為gcc -o,
第二個(gè)定義使用"+="在前面定義的CC后附加了-O2,從而CC最終的值是gcc -o
-O2.
除用戶定義變量外,make也允許使用環(huán)境變量,自動(dòng)變量和預(yù)定義變量.使用環(huán)境變量非常簡單.在啟動(dòng)時(shí),make讀取已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量.但是,如果makefile中有同名的變量,則這個(gè)變量將取代與之相應(yīng)的環(huán)境變量,所以應(yīng)當(dāng)注意這一點(diǎn).
自動(dòng)變量
變量
說明
$@
規(guī)則的目標(biāo)所對應(yīng)的文件名
$<
規(guī)則中的第一個(gè)相關(guān)文件名
$^
規(guī)則中所有相關(guān)文件的列表,以空格為分界符
$?
規(guī)則中日期新于目標(biāo)的所有相關(guān)文件的列表,以空格為分隔符
$(@D)
目標(biāo)文件的目錄部分(如果目標(biāo)在子目錄中)
$(@F)
目標(biāo)文件的文件名部分(如果目標(biāo)在子目錄中)
用于文件名和標(biāo)志的預(yù)定義變量
變量
說明
AR
歸檔維護(hù)程序,默認(rèn)值=ar
AS
匯編程序,默認(rèn)值=as
CC
C編譯程序,默認(rèn)值=cc
CPP
C預(yù)處理程序,默認(rèn)值=
cpp
RM
文件刪除程序,默認(rèn)值="rm -f"
ARFLAGS
傳給歸檔維護(hù)程序的標(biāo)志,默認(rèn)值=rv
ASFLAGS
傳給匯編程序的標(biāo)志,沒有默認(rèn)值
CFLAGS
傳給C編譯器的標(biāo)志,沒有默認(rèn)值
CPPFLAGS
傳給C預(yù)處理程序的標(biāo)志,沒有默認(rèn)值
LDFLAGS
傳給鏈接程序(ld)的標(biāo)志,沒有默認(rèn)值