makefile簡明使用方法

零碎

命令前面加一個減號的意思是,該命令如果出錯也不停止
命令前面加@的意思是,這個命令將不顯示出來

makefile中的變量其實就是C語言中的宏

:=定義的變量不能使用後面定義的變量
=定義的變量可以使用後面的變量
+=是追加
例如,

a=5$(b)
c:=5$(b)
b=M

b是5M,c是5

VPATH變量
make會在當前目錄找不到依賴文件和目標文件的情況下,到VPATH指定的目錄中取尋找文件。

變量的替換

$(var:a=b)
把變量var中所有以a字串結尾的單詞的結尾的a字串替換成b字串

foo := a.o b.o c.o
bar := $(foo:.o=.c)
bar的值爲a.c b.c c.c

還可以進行更精確的控制:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)

if和define

有若干關鍵字實現條件控制:ifeq、ifneq、else、endif、ifdef、ifndef
define用來實現多行變量,以endef結尾

靜態模式

<targets> : <target-pattern> : <prereq-patterns>
	<commands>

看一個例子:

objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
	$(CC) -c $(CFLAGS) $< -o $@

模式規則

模式規則中,目標的定義需要有%字符,%表示一個或多個任意字符:

%.o : %.c 
	<command>

其指出了怎麼從所有的 [.c] 文件生成相應的 [.o] 文件的規則。如果要生成的目標是“a.o b.o”,那麼“%c”就是“a.c b.c”。

自動化變量

$@: 表示規則中的目標文件集。如果有多個目標,那麼“$@”就是匹配於目標中模式定義的集合。
$<: 依賴目標中的第一個目標名字。如果依賴目標是以模式(即“%”)定義的,那麼“$<”將是符合模式的一系列的文件集。注意,其是一個一個取出來的。 
$^: 所有的依賴目標的集合。以空格分隔。如果在依賴目標中有多個重複的,這個變量會去除重複的依賴目標,只保留一份。
$+: 這個變量很像“$^”,也是所有依賴目標的集合。只是它不去除重複的依賴目標。

$@、$<在擴展時只會有一個文件,$^、$+的值是一個文件列表。

常用函數

讓通配符在變量中展開:
objects := $(wildcard *.o)

$(shell <command>)
新生成一個shell進程來執行命令

$(call <expression>,<param1>,<param2>...)
舉個例子,
foo = $(2) $(1)
bar = $(call foo,a,b)
那bar的值就是b a

$(if <condition>,<then-part>)
$(if <condition>,<then-part>,<else-part>)

$(foreach <var>,<list>,<text>)
把參數<list>中的單詞逐一取出放到參數<var>所指定的變量 中,然後再執行<text>所包含的表達式。每一次會返回一個字符串,循環過程中,每次所返回的每個字符串會以空格分隔,最後當整個循環結束時,最後返回整個字符串(以空格分隔)。
例如,
names := a b c
files := $(foreach n,$(names),$(n).o)
files的值是a.o b.o c.o

字符串處理函數
以下<text>表示的是一組單詞

$(subst <from>,<to>,<text>)
字符串替換
$(subst ee,EE,feet on the street)

$(patsubst <pattern>,<replacement>,<text>)
模式字符串替換,查找<text>中單詞是否符合模式<pattern>,如果匹配的話,則以<replacement>替換
$(patsubst %.c,%.o,x.c.c bar.c)

$(strip <string>)
取出開頭和結尾的空字符

$(findstring <find>,<in>)
在字串<in>中查找<find>字串,如果找到返回<find>,否則返回空

$(filter <pattern>,<text>)
以<pattern>模式過濾<text>字串中的單詞

$(filter-out <pattern>,<text>)
與filter相反

$(sort <text>)
排序並去重

$(word <n>,<text>)
取字串<text>中的第<n>個單詞(從1開始)

$(wordlist <b>,<e>,<text>)
取字串<text>中的第<b>到第<e>個單詞(前後都是閉區間)

$(words <text>)
統計單詞個數

$(firstword <text>)
取第一個單詞

文件名操作函數
以下<names>表示的是一組文件名

$(dir <names>)
取目錄
$(dir src/foo.c hacks) 返回值是 "src/ ./"

$(notdir <names>)
取文件函數

$(suffix <names>)
取後綴函數(文件後綴名)

$(basename <names>)
取basename

$(addsuffix <suffix>,<names>)
添加後綴

$(addprefix <prefix>,<names>)
添加前綴

參考

跟我一起寫 Makefile (陳皓)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章