Makefile的函数提供了处理文件名,变量,文本和命令的方法。使用函数可以使Makefile的书写更加的灵活。函数的机制也是在调用函数的地方,将函数的处理结果替换原来的函数,简单举例如下:
objects = $(patsubst .c,.o,$(wildcard *.c))
以上就是将patsubst函数的运行结果(将当前工作目录的所有包含".c"文件的文件名的文本替换为".o"文件名),赋值给objects。函数的输出结果替换了patsubst函数。
1.格式:
$(FUNCTION ARGUMENT)
或者
${FUNCTION ARGUMENTS}
2.说明:
1. 语法中"FUNCTION"是需要调用的函数名,应该是make内嵌的函数名。对于用户自定义的函数名需要通过make的"call"函数来间接调用。
2. "ARGUMENTS"是函数的参数,参数和函数之间建议使用空格分开,如果存在多个参数,参数之间使用逗号","分开。
3. 以"$"开头,使用成对的圆括号或花括号把函数名和参数括起来。
4. 函数处理参数时,参数如果存在对其他变量或函数的引用,首先对这些引用进行展开得到参数的实际内容,而后对它们进行处理。函数的展开顺序按照参数的先后顺序来进行。
5. 书写时,函数的参数不能出现逗号","和空格。这是因为逗号被用于多个参数的分隔符,而空格会被忽略。当实际书写Makefile时,当有逗号或者空格作为函数的参数时,需要把它们赋值给一个变量,在函数的参数中引用这个变量。示例如下:
[root@localhost makefile]# vim test1.mk
comma:=,
empty:=
space:=$(empty) $(empty)
foo:=a b c
bar:=$(subst $(space),$(comma),$(foo))
$(warning $(bar))
all:
@echo hello
结果:
[root@localhost makefile]# make -f test1.mk all
test1.mk:8: a,b,c
hello
1. $(subst FROM,TO,TEXT)
字符串替换函数。将字符串"TEXT"中的"FROM"字符替换为"TO",返回替换后的新字符串。示例如下:
target=$(subst ee,EE,feet on the street)
结果:
target=fEEt on the street
2. $(patsubst PATTERN,REPLACEMENT,TEXT)
模式替换函数。搜索"TEXT"中以空格分开的字符串,将符合模式"PATTERN"的字符串替换为"REPLACEMENT"的字符串。参数"PATTERN"中可以使用模式通配符"%"来代表一个字符串的若干字符。如果参数"REPLACEMENT"中也包含一个"%",那么"REPLACEMENT"中的"%"将是"PATTERN"中的那个"%"所代表的字符串。示例如下:
src:=a.c b.c c.c
objects=$(patsubst %.c,%.o,$(src))
结果:
objects=a.o b.o c.o
变量替换引用"patsubst"函数的简化版:
2.1. $(VAR:PATTERN=REPLACEMENT) = $(patsubst PATTERN,REPLACEMENT,$(VAR))
举例如下:
objects:=a.o b.o c.o
src:=$(objects:.o=.c)
结果:
src=a.c b.c c.c
2.2. $(VAR:SUFFIX=REPLACEMENT) = $(patsubst %SUFFIX,%REPLACEMENT,$(VAR))
举例如下:
objects:=a.o b.o c.o
src:=$(objects:%.o:%.c)
结果:
src=a.c b.c c.c
3. $(strip STRING)
去空格的函数。去掉字符串"STRING"开头和结尾的空字符(空格或tab字符),并将字符串"STRING"内部的多个空格合并为一个空字符。示例如下:
empty:=
multi_space:=$(empty) $(empty)
src:=$(multi_space) a.c b.c c.c
result:=$(strip $(src))
结果:
src= a.c b.c c.c
result=a.c b.c c.c
4. $(findstring FIND,IN)
查找字符串函数。在字符串"IN"中查找"FIND"字符串,如果字符串"IN"中存在字符串"FIND",则返回"FIND",否则为空。示例如下:
result:=$(findstring a,a b c)
结果:
result=a
5. $(filter PATTERN...,TEXT)
过滤函数。过滤掉字符串"TEXT"中所有不符合模式"PATTERN"的字符串,保留符合"PATTERN"的字符串,可以有多个"PATTERN"。"PATTERN"字符串中一般需要包含模式字符"%",存在多个模式时,模式表达式之间使用空格分隔。示例如下:
src:=a.c b.c c.s d.h
result:=$(filter %.c %.s,$(src))
结果:
result=a.c b.c c.s
6. $(filter-out PATTERN...,TEXT)
反过滤函数。和"filter"函数实现的功能相反,过滤掉字符串"TEXT"中所有符合"PATTERN"的字符串。保留所有不符合此模式的字符串。可以有多个模式,存在多个模式时,模式表达式之间使用空格分隔。返回"TEXT"字符串中不符合"PATTERN"的字符串。示例如下:
src:=a.c b.c c.s d.h
result:=$(filter-out %.c %.s,$(src))
结果:
result=d.h
7. $(word N,TEXT)
取单词函数。取出多个字符串"TEXT"中第"N"个单词(N的值从1开始)。函数返回"TEXT"中第N个单词。示例如下:
result:=$(word 2,aaa bbb ccc ddd)
结果:
result=bbb
8. $(wordlist S,E,TEXT)
取字符串函数。从多个字符串"TEXT"中取出从"S"开始到"E"的字符串。函数返回多个字符串"TEXT"中从"S"到"E"的单词字符串。示例如下:
result=$(wordlist 2,3,aaa bbb ccc ddd eee)
结果:
result=bbb ccc
9. $(words TEXT)
统计字符串数目函数。函数返回"TEXT"中字符串数目。示例如下:
result=$(words aaa bbb ccc ddd eee)
结果:
result=5
10. $(firstword NAMES...)
取首个字符串函数。函数返回"NAMES"第一个字符串。firstword函数的功能等效于$(word 1,NAMES...)。示例如下:
result=$(firstword aaa bbb ccc ddd)
结果:
result=aaa
1. $(dir NAMES...)
取目录函数。从文件名序列"NAMES..."中取出各个文件名的目录部分。文件名的目录部分就是包含在文件名中的最后一个斜线("/")之前的部分。函数返回文件序列"NAMES..."中每一个文件的目录部分,如果文件名中没有斜线,认为此文件为当前目录("./")下的文件。示例如下:
result=$(dir src/foo.c a/b/x.c aaa bbb)
结果:
result=src/ a/b/ ./ ./
2. $(notdir NAMES...)
取文件名函数。从文件名序列"NAMES"中取出非目录部分。目录部分是指最后一个斜线("/")之前的部分。删除所有文件名中的目录部分,只保留非目录部分。函数返回文件名序列"NAMES"中每一个文件的非目录部分。函数的一个缺陷是文件名不能包含空格,否则会有问题。举例如下:
result:=$(notdir src/a.c include/a.h aaa bbb ccc)
结果:
result=a.c a.h aaa bbb ccc
3. $(suffix NMAES...)
取后缀函数。从文件名序列"NAMES"中取出各个文件名的后缀(文件名中最后一个以点"."开始的部分),如果文件名中不包含点号,则为空。函数返回以空格分隔的"NAMES..."中每一个文件的后缀序列。如果"NAMES..."是多个文件名时,返回值是多个以空格分隔开的字符串序列,如果文件名没有后缀部分,则返回空。示例如下:
result=$(suffix src/a.c include/a.h b.c d)
结果:
result=.c .h .c
4. $(basename NAMES...)
取前缀函数。从文件名序列"NAMES..."中取出各个文件名的前缀部分(点号之前的部分)。函数返回空格分隔的文件名序列"NAMES..."中各个文件的前缀序列,如果文件名没有前缀,则返回为空。如果"NAMES..."中包含没有后缀的文件名,此文件名不改变,如果一个文件名中存在多个点号,则返回文件名中最后一个点号之前的文件名部分。示例如下:
result=$(basename src/a.c include/b.h /home/god/x.a.c jacks)
结果:
result=src/a include/b /home/god/x.a jacks
5. $(addsuffix SUFFIX,NAMES...)
加后缀函数。为"NAMES..."中的每一个文件名添加后缀"SUFFIX"。参数"NAME..."为空格分隔开的文件名序列,将"SUFFIX"追加到此序列的每一个文件名的末尾。函数返回添加了后缀"SUFFIX"的文件名序列。示例如下:
result:=$(addsuffix .c,aaa bbb ccc)
结果:
result=aaa.c bbb.c ccc.c
6. $(addprefix PREFIX,NAMES...)
加前缀函数。为"NAMES"中的每一个文件名添加前缀"PREFIX"。参数"NAMES..."是空格分隔开的文件名序列,将"PREFIX"添加到此序列的每一个文件名之前。函数返回以单空格分隔的添加了前缀"PREFIX"的文件名序列。示例如下:
result=$(addprefix src/,a.c b.c c.c d.c)
结果:
result=src/a.c src/b.c src/c.c src/d.c
7. $(join LIST1,LIST2)
单词连接函数。将字符串序列"LIST1"和字符串"LIST2"的各个字符串对应连接,将"LIST2"中的第一个字符串追加到"LIST1"的第一个字符串后合并为一个单词,将"LIST2"中的第二个字符串追加到"LIST1"的第二个字符串后合并为一个单词,等等,以此类推。函数返回单空格分隔的合并后的字符串序列。示例如下:
result=$(join a b c,.c .h)
结果:
result=a.c b.h c
8. $(wildcard PATTERN)
获取匹配模式文件名函数。函数的作用是列出当前目录下所有符合模式"PATTERN"格式的文件名。函数返回以空格分隔的,存在当前目录下的所有符合模式"PATTERN"的文件名。"PATTERN"使用shell可以识别的通配符,包括"?","*"等。
本文主要介绍了make的函数的用法,其中主要介绍了文本处理函数和文件名处理函数。文本处理函数有subst,patsubst,strip,findstring,filter,filter-out,sort,word,wordlist,words和firstword。文件名处理函数有dir,notdir,suffix,basename,addsuffix,addprefix,join和wildcard。