在makefile中可以使用函数来处理变量,从而使用户的命令和规则更灵活,函数调用后,函数的返回值可以当做变量来使用。
一、函数调用的语法
makefile文件中的函数调用以$标示,其语法如下:
$(<function> <argumnets>)
或者
${<function> <argumnets>}
<function>表示函数名,<arguments>表示函数的参数列表。参数间以“,”分隔,而函数名之间以空格分隔。
二、字符串处理函数
1.字符串替换函数
表达式:
$(subst<from>,<to>,<text>)
函数功能:把字串<text>中的<from>字符串替换成<to>。
返回值:函数返回被替换后的字符串。该函数调用示例如下:
result = $(subst a,A, how are you, China?)
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果为:
2.模式字符串替换函数
表达式:
$(patsubst<pattern>,<replacement>,<text>)
函数功能:查找<text>中的单词
返回值:函数返回被替换后的字符串。
该函数调用示例如下,其中,makefile将文件列表中的.mk文件替换为.o文件。
result = $(patsubst %.mk, %.o, makefile.mk.mk a.mk)
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果:
3.去空格函数
表达式:
$(strip<string>)
函数功能:去掉<string>字串中开头和结尾的空字符
返回值:返回被去掉空格的字符串值
该函数的示例如下:
result = $(strip hello world )
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果如下:
4.查找字符串函数
表达式:
$(findstring <find>,<in>)
函数功能:在字符串<in>中查找<find>字串
返回值:如果找到指定的字符串,则返回<find>,否则返回空字符串
示例如下:
result = $(findstring h,hello)
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果:
5.过滤函数
表达式:
$(filter <pattern>,<text>)
函数功能:以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词,可以有多个模式。
返回值:返回符合模式<pattern>的字符串。
该函数示例如下,将文件列表中是.c和.h的文件过滤掉:
sources := a.c b.c c.c d.h e f
result = $(filter %.c %.h,$(sources))
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果:
6.反过滤函数
表达式:
$(filter-out <pattern>,<text>)
函数功能:以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词,可以有多个模式。
返回值:返回不符合模式<pattern>的字符串。
示例如下:
sources := a.c b.c c.c d.h e f
result = $(filter-out %.c %.h,$(sources))
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果:
7.排序函数
表达式:
$(sort <list>)
函数功能:给字符串<list>中的单词排序(升序)
返回值:返回排序后的字符串。
示例如下,将hello world china字符串排序:
result = $(sort hello world china)
all :
echo -n "the result is : "
echo $(result)
.PHONY : all
执行结果:
注:sort函数回去掉<list>中相同的单词。
8.取单词函数
表达式:
$(word <n>,<text>)
函数功能:取字符串<text>中第<n>个单词
返回值:返回字符串<text>中第<n>个单词。
示例如下:
result1 = $(word 2, hello world china) #取单词world
result2 = $(word 4, hello world china) #取一个不存在的单词
all :
echo -n "the result1 is : "
echo $(result1)
echo -n "the result2 is : "
echo $(result2)
.PHONY : all
执行结果:
9.取单词串函数
表达式:
$(wordlist <s>,<e>,<text>)
函数功能:从字符串<text>中取<s>开始到<e>的单词串。<s>和<e>是一个数字。
返回值:返回字符串<text>中从<s>到<e>的单词字串。
该函数示例如下:
result1 = $(wordlist 1,2, hello world china) #取单词串
result2 = $(wordlist 3,2, hello world china) #取单词串
result3 = $(wordlist 2,5, hello world china) #取单词串
all :
echo -n "the result1 is : "
echo $(result1)
echo -n "the result2 is : "
echo $(result2)
echo -n "the result3 is : "
echo $(result3)
.PHONY : all
执行结果:
10.单词个数统计函数
表达式:
$(words <text>)
函数功能:统计<text>中字符串中的单词个数
返回值:返回<text>中的单词数。
示例如下:
result = $(words hello world china)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
11.首单词函数
表达式:
$(firstword <text>)
函数功能:取字符串<text>中的第一个单词。
返回值:返回字符串<text>的第1个单词。
示例如下:
result = $(firstword hello world china)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : al
执行结果:
三、文件名操作函数
1.取目录函数
表达式:
$(dir <names...>)
函数功能:从文件名序列<names>中取出目录部分(目录部分是指最后一个 / 之前的部分,如果没有 / ,则返回“./ ”)
返回值:返回文件名序列<names>的目录部分。
该函数示例如下:
result = $(dir text.c /home/admin/text.c)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
2.取文件函数
表达式:
$(notdir <names...>)
函数功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个“/”之后的部分。
返回值:返回文件名序列<names>中的非目录部分
示例如下:
result = $(notdir text.c /home/admin/text.c)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
3.取后缀函数
表达式:
$(suffix <names...>)
函数功能:从文件名序列<names>中取出各个文件名的后缀
返回值:文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字符串。
该函数示例如下:
result = $(suffix text.txt /home/admin/text.c file)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : al
执行结果:
4.取前缀函数
表达式:
$(basename <namses...>)
函数功能:从文件名序列<names>中取出文件名的前缀部分
返回值:文件名序列<names>的前缀序列,如果没有前缀,返回空字符串。
示例如下:
result = $(basename text.txt /home/admin/text.c file)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
5.加前缀函数
表达式:
$(addsuffix <suffix>,<names...>)
函数功能:把后缀<suffix>加到<names>中的每个单词后面
返回值:返回加过后缀的文件名序列。
示例如下,相当于添加一个扩展名“
result = $(addsuffix .c,a b c)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
6.加前缀函数
表达式:
$(addprefix <prefix>,<names...>)
函数功能:
把前缀<prefix>加到<names>中每个单词的前面
返回值:返回加过前缀的文件名序列。
示例如下:
result = $(addprefix /home/admin/,text1.c text2.c text3,c)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
7.连接函数
表达式:
$(join <list1>,<list2>)
函数功能:把<list2>中的单词对应地加到<list1>的单词后面
返回值:返回连接后的字符串。
示例如下:
result1 = $(join /home/ /home/,text1.c text2.c text3,c)
result2 = $(join /home/ /home/ /home/,text1.c text2.c)
all :
echo -n "the result1 is : "
echo $(result1)
echo -n "the result1 is : "
echo $(result2)
.PHONY : all
执行结果:
四、foreach函数
foreach函数是用来控制循环的。语法如下:
$(foreach <var>,<list>,<text>)
<var>最好是一个变量名,<list>可以是一个表达式,而<text>中一般会使用<var>参数来依次枚举<list>中的单词。
示例:
names := a b c d
result = $(foreach n,$(names),$(n).c)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
注意:foreach函数中的<var>参数是一个临时变量。因此,foreach函数执行完后,<var>将不再起作用,其作用域只在foreach函数中。
五、if函数
if函数很像makefile文件中所支持的条件语句--ifeq,语法如下:
$(if <condition>,<then-part>)
或者
$(if <condition>,<then-part>,<else-part>)
<condition>参数表示一个条件表达式,如果该表达式为真,则执行<then-part>中的语句,否则执行<else-part>。
示例:
a := 1
b := 1
result = $(if ifeq($a, $b), $a = 10, $b = 10)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
六、call函数
call函数为用户创建一个自己定义的函数。用户写的一个表达式,每次用到这个表达式的时候,使用call函数跳转到该表达式处执行即可,语法为:
$(call <expression>,<parm1>,<parm2> ...)
当make执行这个函数时,<expression>参数中的变量,会被参数<parm1>,<parm2>等依次取代,而<expression>的返回值就是call函数的返回值。
示例:
add = $(1) + $(2)
result := $(call add,1,2)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果:
七、shell函数
shell函数用来执行shell命令。该函数把执行操作系统命令后的输出作为函数返回,用户可以通过调用shell函数,使用操作系统命令来生成一个变量。格式如下:
$(shell <command>,<parm1>,<aprm2> ...)
这个函数会生成一个新的进程执行shell命令,所以该函数会影响运行性能。如果在makefile中大量使用该函数,会导致makefile文件执行效率严重下降。
示例:
result := $(shell ls)
all :
echo -n "the result1 is : "
echo $(result)
.PHONY : all
执行结果: