$(subst <from>,<to>,<text>)
名稱:字符串替換函數(shù)——subst。
功能:把字串<text>中的<from>字符串替換成<to>。
返回:函數(shù)返回被替換過后的字符串。
示例:
$(subst ee,EE,feet on the street),
把“feet on the street”中的“ee”替換成“EE”,返回結(jié)果是“fEEt on the strEEt”。
$(patsubst <pattern>,<replacement>,<text>)
名稱:模式字符串替換函數(shù)——patsubst。
功能:查找<text>中的單詞(單詞以“空格”、“Tab”或“回車”“換行”分隔)是否符合模式<pattern>,如果匹 配的話,則以<replacement>替換。這里,<pattern>可以包括通配符“%”,表示任意長度的字串。如 果<replacement>中也包含“%”,那么,<replacement>中的這個“%”將 是<pattern>中的那個“%”所代表的字串。(可以用“\”來轉(zhuǎn)義,以“\%”來表示真實含義的“%”字符)
返回:函數(shù)返回被替換過后的字符串。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.c bar.c”符合模式[%.c]的單詞替換成[%.o],返回結(jié)果是“x.c.o bar.o”
備注:
這和我們前面“變量章節(jié)”說過的相關(guān)知識有點(diǎn)相似。如:
“$(var:<pattern>=<replacement>)”
相當(dāng)于
“$(patsubst <pattern>,<replacement>,$(var))”,
而“$(var: <suffix>=<replacement>)”
則相當(dāng)于
“$(patsubst %<suffix>,%<replacement>,$(var))”。
例如有:objects = foo.o bar.o baz.o,
那么,“$(objects:.o=.c)”和“$(patsubst %.o,%.c,$(objects))”是一樣的。
$(dir <names...>)
名稱:取目錄函數(shù)——dir。
功能:從文件名序列<names>中取出目錄部分。目錄部分是指最后一個反斜杠(“/”)之前的部分。如果沒有反斜杠,那么返回“./”。
返回:返回文件名序列<names>的目錄部分。
示例: $(dir src/foo.c hacks)返回值是“src/ ./”。
$(notdir <names...>)
名稱:取文件函數(shù)——notdir。
功能:從文件名序列<names>中取出非目錄部分。非目錄部分是指最后一個反斜杠(“/”)之后的部分。
返回:返回文件名序列<names>的非目錄部分。
示例: $(notdir src/foo.c hacks)返回值是“foo.c hacks”。
$(suffix <names...>)
名稱:取后綴函數(shù)——suffix。
功能:從文件名序列<names>中取出各個文件名的后綴。
返回:返回文件名序列<names>的后綴序列,如果文件沒有后綴,則返回空字串。
示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是“.c .c”。
$(basename <names...>)
名稱:取前綴函數(shù)——basename。
功能:從文件名序列<names>中取出各個文件名的前綴部分。
返回:返回文件名序列<names>的前綴序列,如果文件沒有前綴,則返回空字串。
示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar hacks”。
$(addsuffix <suffix>,<names...>)
名稱:加后綴函數(shù)——addsuffix。
功能:把后綴<suffix>加到<names>中的每個單詞后面。
返回:返回加過后綴的文件名序列。
示例:$(addsuffix .c,foo bar)返回值是“foo.c bar.c”。
$(addprefix <prefix>,<names...>)
名稱:加前綴函數(shù)——addprefix。
功能:把前綴<prefix>加到<names>中的每個單詞后面。
返回:返回加過前綴的文件名序列。
示例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。
foreach 函數(shù)
foreach函數(shù)和別的函數(shù)非常的不一樣。因為這個函數(shù)是用來做循環(huán)用的,Makefile中的foreach函數(shù)幾乎是仿照于Unix標(biāo)準(zhǔn)Shell(/bin/sh)中的for語句,或是C-Shell(/bin/csh)中的foreach語句而構(gòu)建的。它的語法是:
$(foreach <var>,<list>,<text>)
這個函數(shù)的意思是,把參數(shù)<list>中的單詞逐一取出放到參數(shù)<var>所指定的變量中,然后再執(zhí)行<text>所包含的表達(dá)式。每一次<text>會返回一個字符串,循環(huán)過程中,<text>的所返回的每個字符串會以空格分隔,最后當(dāng)整個循環(huán)結(jié)束時,<text>所返回的每個字符串所組成的整個字符串(以空格分隔)將會是foreach函數(shù)的返回值。
所以,<var>最好是一個變量名,<list>可以是一個表達(dá)式,而<text>中一般會使用<var>這個參數(shù)來依次枚舉<list>中的單詞。舉個例子:
names := a b c d
files := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的單詞會被挨個取出,并存到變量“n”中,“
$(n).o”每次根據(jù)“$(n)”計算出一個值,這些值以空格分隔,最后作為
foreach函數(shù)的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
自用例子Makefile:
一、自動輸出目錄和lib庫名稱
版本一:
這個例子的作用是根據(jù)所提供的lib全路徑, 自動分拆成為-L和-l,以供GCC編譯時指定
MYLIBS = /lib/lib2.a
MYLIBS += /lib/lib3.a
MYLIBS += /lib/lib4.a libb.a
PP = $(sort $(foreach lb,$(MYLIBS),-l$(patsubst lib%.a,%,$(notdir $(lb))) -L$(dir $(lb))))
ps2:
@echo $(PP)
結(jié)果輸出:
$ make ps2
-L./ -L/lib/ -l2 -l3 -l4 -lb
函數(shù)使用說明:
foreach 用于將每個全路徑轉(zhuǎn)換為-L和-l
patsubst 模式替換用于生成-l,取出lib名稱
dir用于生成-L
sort主要用于排序,更重要的作用是用于去除重名,當(dāng)然如果由于庫的引用的依賴關(guān)系,比如上面的庫b必須引用庫2,按照gcc的要求,庫2必須放在庫b的后面,那么上面的排序結(jié)果就不是我們所想要的。那么就只有去除sort函數(shù)的調(diào)用,直接使用foreach的返回結(jié)果即可。
版本二:
下面的代碼克服了上面所說的sort引起的問題。
MYLIBS = /lib/lib2.a
MYLIBS += /lib/lib4.a libb.a
MYLIBS += /lib/lib3.a
PPPATH = $(sort $(foreach lb,$(MYLIBS),-L$(dir $(lb))))
PPNAME = $(foreach lb,$(MYLIBS),-l$(patsubst lib%.a,%,$(notdir $(lb))))
ps2:
@echo $(PPPATH) $(PPNAME)
二、MAKEFILE變量引用與SHELL變量引用區(qū)別
如果要引用SHELL中export的變量,則應(yīng)該使用$$NAME的方式進(jìn)行,
如果要引用MAKEFILE中定義的變量則應(yīng)該用$(NAME)的方式進(jìn)行