PS:直接从WORD拷贝,未对格式进行仔细整理
7 函数
在makefile中,还可以使用函数。函数分为两类:一种是makefile自带的函数,称之为内置函数;一种是用户自定义函数,也就是说我们可以自己在makefile中编写函数。
内置函数又大致可分为:文本处理函数,文件名称处理函数,条件和流程控制函数,变量操作函数,系统函数。
在makefile中调用函数的语法如下:
$(函数名称 函数参数 [, 函数参数[,...]])
在本章节剩下的内容中,将按函数的分类罗列出makefile中主要的内置函数。由于内置函数较多,只会对其中小部分给出例子,其他都只说明函数的用途。
关于用户自定义函数,这里就不介绍了,读者如果感兴趣,可以自行查找资料。
7.1 文本处理函数
文件处理函数是用来处理make变量的,在makefile中变量的值都是字符串类型的(即文本类型)
1. $(subst find_text, replacement_text, original_text)
作用:把文本original_text中出现的每个find_text替换为replacement_text后再展开。
例1 使用subst函数
env.txt文件:
project/src;project/include;project/obj
build.bat批处理文件:
……
set /P PRO_FILE_PATH = <env.txt
make –f substExample.mk
……
substExample.mk文件:
……
VPATH = $(subst ;,:,$( PRO_FILE_PATH))
……
在例20中,我们将项目文件的所在的路径保存在了env.txt中,每个路径用分号分割;我们希望在VPATH内置变量中使用这些路径,但是VPATH中路径又是用冒号分割的,因此使用subst函数将分号替换成冒号。2. $(patsubst PATTERN,REPLACEMENT,TEXT)
2. $(patsubst find_pattern, replacement_pattern, original_text)
作用:将文本original_text中满足find_pattern模式的内容替换成replacement_pattern模式的文本。
例2 使用patsubst函数
SRCFILES := circle.c square.c triangle.c rectangle.c
shapes:$(patsubst %.c,%.o,$(SRCFILES))
$(CC) $(LDFLGAS) –o $@ $^
%.o : %.c
$(CC) $(CFLAGS) –o $@ –c $<
例21的makefile与下面makefile是等同的:
shapes:circle.o square.o triangle.o rectangle.o
$(CC) $(LDFLGAS) –o $@ $^
%.o : %.c
$(CC) $(CFLAGS) –o $@ –c $<
3. $(strip original_text)
作用:删除文本original_text前面和后面的空白(white space),并将中间每个“没有引号围起来”的空格序列替换为一个空格字符
4. $(findstring find_text, original_text)
作用:如果在original_text内找到匹配的字符串,就展开为find_text的值;如果没有找到,就展开为空值。
例如:
$(findstring a,a b c)
$(findstring a,b c)
就分别展开为“a”和“”(空字符串)。
5. $(filter find_patterns, original_text)
作用:在original_text中删除所有与任一个find_patterns都不匹配的词,只返回匹配的词。
例3 使用filter函数
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
gcc $(filter %.c %.s, $(sources)) -o foo
展开后与下面的makfile等同:
foo: foo.c bar.c baz.s ugh.h
gcc foo.c bar.c baz.s –o foo
6. $(filter-out find_patterns, original_text)
作用:在original_text中删除所有与find_patterns匹配的词,只返回不匹配的词。它与函数filter正好相反。
7. $(sort original_text)
作用:按字母顺序排列original_text内的词(word),并删除重复元素后展开。
8. $(word n, original_text)
作用:展开为original_text内的第n个词(word)
9. $(firstword original_text)
作用:与$(word 1, original_text)等同
10. $(wordlist n,m,original_text)
作用:展开为original_text内的第n个词(word)到第m个词
11. $( words original_text)
作用:展开为original_text内的词(word)的数量
7.2 文件名称处理函数
1. $(dir filename_list)
作用:展开为变量filename中每个文件名的目录部分列表
例如:$(dir src/foo.c hacks)展开后为“src/ ./”。
2. $(notdir filename_list)
作用:展开为变量filename文件名列表,删除目录部分
例如:$(notdir src/foo.c hacks) 展开后为“foo.c hacks”。
3. $(suffix filename_list)
作用:展开为扩展名
例如:$(suffix src/foo.c hacks) 展开后为“.c”。
4. $(basename filename_list)
作用:展开为文件名列表,删除它们的扩展名,目录部分不变动。
例如:$(basename src/foo.c hacks) 展开后为“src/foo hacks”。
5. $(addsuffix suffix,filename_list)
作用:展开为文件名,并在后面加上后缀suffix。
例如:$(addsuffix .c, foo bar) 展开后为“foo.c bar.c”。
6. $(addprefix prefix,filename_list)
作用:展开为文件名,并加上前缀prefix。
例如:$(addprefix src/, foo bar)展开后为“src/foo src/bar”。
7. $(join prefix_list,suffix_list)
作用:把两个参数一个词一个词地结合起来。如果某个参数的词的个数比另一个多,多出来的词不加变化地复制到结果中。
例如:“$(join a b,.c .o)” 展开后为“a.c b.o”。
8. $(wildcard glob)
作用:展开为“符合glob模式”的既有文件名,这个模式通常包含shell通配符。
7.3 条件和流程处理函数
这里列出的函数,可以进行有条件的操作,迭代地处理列表,或者执行一个变量的内容。
1. $(foreach var, list, expression)
作用:遍历list中的每个词并赋给临时变量var,在将var的结果根据表达式expression扩展;将每次遍历扩展的结果通过空格进行连接,生成foreach的最终结果。
例4 使用foreach函数(1)
dirs := project/src project/include
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
假设在project/src目录下有如下文件:circle.c square.c, 在project/include目录下有如下文件:circle.h, square.h,则变量files最终的值为“project/src/circle.c project/src/square.c project/include/ circle.h project/include/square.h”。 files变量的值为两个目录下所有文件的完整文件名列表。
如果我们只想列出两个目录下所有文件的文件名,则可以这么做:
例5 使用foreach函数(2)
dirs := project/src project/include
files := $(foreach dir,$(dirs),$(notdir, $(wildcard $(dir)/*) ))
files的值将是“circle.c square.c circle.h, square.h”
2. $(if conditon, then_text[, else_text])
作用:如果删除文本conditon前面和后面的空格后,展开为非空,则展开为then_text,否则展开为else_text
3. $(eval text)
作用:把text展开视为被包含的makefile文字。
7.4 变量操作函数
1. $(value variable_name)
作用:展开为变量名称的“原始”值,没有进一步展开它可能包含的任何变量引用。
2. $(origin variable_name)
作用:展开为如下值中的一个,来指示变量是如何被定义的:
undefined
variable未被定义。
default
variable有一个缺省定义。注意,如果重新定义了一个缺省变量,返回的就是后一个定义的原因。
environment
variable被定义为环境变量,而且没有打开“-e”选项。
environment override
variable被定义为环境变量,“-e”选项被打开。
file
variable在一个构造文件中被定义。
command line
variable在命令行中被定义。
override
variable在一个构造文件中用override指令定义。
automatic
variable是为每条规则所执行的命令定义的自动变量。
3. $(call variable_name, argument[,argument[,…]])
作用:展开变量,把表达式中有编号的变量($1,$2…)替换为保留的变量。实际上,使用此内置函数可以创建自定义类函数宏。
7.5 系统函数
系统函数,可以实现与make环境的交互。
1. $(shell text)
作用:将”text”展开传递给shell。此函数会展开为最终shell命令的标准输出。
2. $(error text)
作用:make把text文字的展开当作错误信息而输出,然后退出。
3. $(warning text)
作用:类似于error命令,不同的是make不会退出。此函数展开为”空”