目录
为了便于Makefile的灵活编写,其中定义了一部分函数供人使用,接下来一一举例。
一、函数定义
在Makefile中函数基本使用方法总是如下,使用$()或${}包含函数以及待处理变量,多个参数用,隔开,函数名和参数之间用空格隔开。其中根据参数不同,形式有一些小的改变。
$(<function><arguments>)
${<function><arguments>}
二、字符串处理函数
2.1 subst
$(subst from,to,i am from a)
$(subst base_test,,$(wildcard ../sim))
subst为字符串替换函数,可以将字符串中的from替换成to,常和$(wildcard)配合使用,配合使用时是可以更改wildcard检索到的目录
2.2 patsubst
$(patsubst %.c,%.o,a.c.c)
return:a.c.o
patsubst为模式字符串替换函数,当a.c.o满足以.c结尾时,将.c替换成.o,通配符%,表示任意长度的字符
功能:查找text中的单词(单词以空格,Tab键,回车键)是否符合模式pattern,如果匹配成功,则以replacement替换。这里的pattern中可以包括通配符%,表示任意长度的字符,如果replacement中也包含%,那么replacement中的%将和pattern中的%表示的是听一个对象。同时可以使用转义符"/"
2.2 strip
$(strip <string>)
$(strip a b)
return a b
去空格函数,可以去掉头尾空格
2.3 findstring
$(findstring a,addr)
查找字符串函数,在addr中查找是否有a,有a返回addr,没有返回空
2.4 filter
$(filter %.c,aaa.c bbb.o ccc.h)
return aaa.c
过滤函数将会过滤掉不符合以.c结尾·的字符串,只返回符合的字符串
2.5 filter-out
$(filter-out %.c,aaa.c bbb.o ccc.h)
return bbb.o ccc.h
反过滤函数将会过滤掉符合以.c结尾的字符串,返回不符合的字符串
2.6 sort
$(sort aa bb cc)
return aa bb cc
排序函数给字符串中的单词按升序排序,返回排序之后的字符串
2.7 word
$(word 3,aa bb cc)
return cc
word函数会取字符串中的第3个单词(从1开始)并返回,如果没有第三个,则返回空字符串
2.8 words
$(words aa bb cc)
return 3
words函数会统计字符串中单词的个数并返回
如果我们想要去取字符串中最后一个单词可以这样用
$(word $(words <text>),<text)
2.9 wordlist
$(wordlist 2,3,foo bar baz)
return bar baz
wordlist函数可以从字符串中取出指定的连续一段数字,例如例子中的2到3,如果不够两个返回空,不够三个返回部分
2.10 firstword
$(firstword aa bb)
return aa
firstword函数返回字符串第一个单词
三、目录结构操作函数
下面的函数将涉及到目录结构操作,一般也可以与上面字符串处理函数混用
3.1 dir
$(dir project/soc/aa.c)
return project/soc/
dir函数会从目录结构中取出目录部分。目录部分是指最后一个反斜杠/以及之前的部分,如果没有反斜杠,那么直接返回./
3.2 notdir
$(notdir project/soc/aa.c)
return aa.c
与dir函数相反,notdir函数返回非目录部分非目录部分是指最后一个反斜杠/之后的部分
3.3 suffix
$(suffix project/aa.c project/b.sv)
return .c .sv
suffix 函数从目录结构中取出文件后缀,如果文件没有后缀,直接返回空字符串
3.4 basename
$(basename project/aa.c project/b.sv)
return aa b
basename 函数与suffix函数相反,会返回前缀文件名
3.5 addsuffix
$(addsuffix .c,aa bb.c)
return aa.c bb.c.c
addsuffix函数把后缀加到参数后面并返回
3.6 addprefix
$(addprefix src/,foo util main)
return src/foo src/util src/main
addprefix函数与addsuffix函数相反,会把前缀加到参数前并返回
3.7 join
$(join <list1>,<list2>)
$(join aaa bbb ccc,111 222 333)
return aaa111 bbb222 ccc333
join函数把list2中的单词对应的加入到list1中单词的后面,如果list1的单词个数要比list2的多,那么list1中多处来的单词保持原样,如果list2的单词个数比list1多,则list2多出来的单词会被复制到list2中,返回链接过的字符串
四、foreach函数
foreach函数和别的函数非常不一样,因为这个函数是用来做循环的,如果之前学过java,我们会知道,java刚好有这个一个循环语句,Makefile中的foreach函数几乎是仿照UNIX标准Shell的for语句实现的。基本语法是
$(foreach <var>,<list>,<text>)
这个函数的意思是,把参数list中的单词逐一取出放在参数var所指定的变量中,然后在执行text所包含的表达式。每次text都会返回一个字符串,循环过程中,text的所返回的每个字符串会以空格分割,最后当整个循环结束是,text所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreache函数的返回值
所以var最好是一个变量名,list可以是一个表达式,text中一般会使用var变量,例如:
names := a b c d
files := $(foreach n,$(names),$(n).o)
return a.o b.o c.o d.o
这里面,变量names中的每一个对象都会被取出来,然后分别赋值给n,然后由变量n执行最后一句话,将所有的内容后面加上.o,所以输出的最后结果是a.o b.o c.o d.o
注意:foreach中的var是一个局部变量,临时的,函数执行完之后,没有意义了
五、if函数
if函数很像GNU的make所支持的条件语句-ifeq,if函数的语法是
$(if <condition>,<then-part>)
#或者是
$(if<condition>,<then-part>,<else-part>)
<condition>参数是if的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,<then-part>会被计算,否则<else-part>会被计算
if函数的返回值是,如果<condition>为真(非空字符串),那个<then-part>会是整个函数的返回值,如果<condition>为假(空字符串),那么<else-part>会是整个函数的返回值,此时如果<else-part>没有被定义,那么,整个函数返回空字串。
六、call函数
call函数是唯一一个可以用来创建新的参数化的函数,我们可以写一个非常复杂的表达式,在表达式中,我们可以定义很多参数,然后你可以用call函数来向这个表达式传递参数,基本语法是:
$(call <expression>,<parm1>,<parm2>,<parm3>...)
当make执行这个函数时,expression参数中的变量,如$(1),$(2),$(3)等,会被参数,,一次取代,而expression的返回值是call函数的返回值,例如:
reverse = $(1) $(2)
foo = $(call reverse ,a ,b)
那么foo的值就是a b。当然参数的次序是可以自定义的,不一定是顺序的,如:
reverse = $(2) $(1)
foo = $(call reverse,a,b)
七、origin函数
origin函数不像其他的函数,他并不操作的值,他只是告诉你这个变量是哪里来的?语法是:
$(origin <variable>)
注意variable是变量的名字,不应该是引用,所以最好不要在variable中使用$字符,origin函数会以其返回值来告诉你这个变量的”出生情况”,origin函数的返回值是undefined,如果variable从来没有定义过,origin函数返回这个值undefined