该篇文章引用了 陈皓老师的《跟我一起写Makefile》,博客地址为:https://blog.csdn.net/haoel/article/details/2886
Mkefile支持使用函数来处理变量,函数的返回值可以再赋值给新的变量,从而使得Makefile的命令、规则更加的灵活智能。
一、函数调用的语法
函数的调用,类似于变量调用,以"$"来调用,语法如下:
$(<func> <arg1>,<arg2>,<arg3>..) 或者 ${<func> <arg1>,<arg2>,<arg3>..}
其中函数中的参数也可以使用变量,举例如下:
comma := ,
empty :=
space := $(empty) $(empty)
foo := a b c
bar := $(subst $(space),$(comma),$(foo))
其中subst函数的功能是替换,,函数原型如下:
$(subst <from>,<to>,<text>)
这个函数有3个参数:
第1个参数是“将要被替换的字符串”
第2个参数是 替换后的字符串
第3个参数是替换操作作用的字符串(拗口),就是要被操作的整个字符串
结合介绍,变量comma是个 逗号 ,empty是 空,space是空格
所以这个函数就是对 变量foo进行替换操作,具体操作是将空格(space)替换成逗号(,)
还有一些别的字符串处理函数,具体遇到了在查手册吧。
二、文件名操作函数
1、 $(dir <name....>)
名称 : 取目录函数——dir
功能 : 从文件名序列names中取出目录部分,目录部分是指最后一个斜杠"/"之前的部分,如果没有
斜杠,那么返回"./"
返回 :返回文件名序列<names> 的目录部分
例如:
$(dir src/foo.c) ,则返回值是"src/"
2、$(notdir <names>)
名称 : 取文件函数,正好跟 上面的 dir函数相反
功能 : 从文件名序列<names>中取出非目录部分,非目录部分是指最后一个斜杠"/"之后的部分
返回 : 文件名
例如:
$(notdir src/foo.c) ,则返回值是foo.c
$(suffix <names...>)
名称:取后缀函数——suffix。
功能:从文件名序列<names>中取出各个文件名的后缀。
返回:返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
示例:$(suffix src/foo.c src-1.0/bar.c)返回值是“.c”。
$(basename <names...>)
名称:取前缀函数——basename。
功能:从文件名序列<names>中取出各个文件名的前缀部分。
返回:返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar”。
$(addsuffix <suffix>,<names...>)
名称:加后缀函数——addsuffix。
功能:把后缀<suffix>加到<names>中的每个单词后面。
返回:返回加过后缀的文件名序列。
示例:$(addsuffix .c,foo bar)返回值是“foo.c bar.c”。
$(addprefix <prefix>,<names...>)
名称:加前缀函数——addprefix。
功能:把前缀<prefix>加到<names>中的每个单词后面。
返回:返回加过前缀的文件名序列。
示例:$(addprefix src/,foo)返回值是“src/foo”。
$(join <list1>,<list2>)
名称:连接函数——join。
功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,
那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,
<list2>多出来的单词将被复制到<list2>中。
返回:返回连接过后的字符串。
示例:$(join aaa bbb , 111 222 333)返回值是“aaa111 bbb222 333”。
三、if函数
if函数类似于Make支持的条件语句——ifeq,语法如下:
$(if <condition>,<then-part>)
或者
$(if <condition>,<then-part>,<else-part>)
也就是if函数可以有else分支,也可以没有,即该函数的参数可以使2个,也可以是3个,condition是判断表达式
如果condition为“非空字符串”,则<then-part>是整个函数的返回值,反之<else-part>是返回值。
四、call函数
call函数可以向表达式传递参数,也可以理解成是替换参数,其语法如下:
$(call <expression>,<parm1>,<parm2>...)
当make执行该函数时,<expression>参数中的变量会依次被<parm1>,<parm2>...依次取代,而<expression>被取代
后的值就是call函数的返回值:
例如:
obj = $(1) $(2)
foo = $(call obj,a,b)
那么foo的值就是 a b
四、shell函数
该函数不像其他参数,它的参数是操作系统shell的命令,即shell函数把执行操作系统命令后的输出作为函数返回,
于是我们可以用操作系统命令以及字符串处理命令awk、sed等命令来生成一个变量,例如:
contents := $(shell cat foo)
files := (shell echo *.c)
这个函数会生成一个shell程序来执行命令,上面的两条命令,第一条命令,变量contents的内容是 foo文件的内容
第二条命令 则是echo的输出