Makefile常用函数.docx
《Makefile常用函数.docx》由会员分享,可在线阅读,更多相关《Makefile常用函数.docx(12页珍藏版)》请在冰豆网上搜索。
Makefile常用函数
Makefile常用函数表
一、函数的调用语法2
二、字符串处理函数2
1.$(substFROM,TO,TEXT)2
2.$(patsubstPATTERN,REPLACEMENT,TEXT)2
3.$(stripSTRINT)3
4.$(findstringFIND,IN)3
5.$(filterPATTERN…,TEXT)3
6.$(filter-outPATTERN...,TEXT)3
7.$(sortLIST)4
8.$(wordN,TEXT)4
9.$(wordlistS,E,TEXT)4
10.$(wordsTEXT)4
11.$(firstwordNAMES…)5
三、文件名处理函数5
1、$(wildcard)5
2、$(dir)5
3、$(notdir)5
4、$(suffix)6
5、$(basename)6
6、$(addsuffix,)6
7、$(addprefix,)6
8、$(join,)6
四、foreach函数7
五、if函数7
六、call函数8
七、origin函数9
八、shell函数10
一、函数的调用语法
函数调用,很像变量的使用,也是以“$”来标识的,其语法如下:
$()
或是
${}
这里,就是函数名,make支持的函数不多。
是函数的参数,参数间以逗号“,”分隔,而函数名和参数之间以“空格”分隔。
函数调用以“$”开头,以圆括号或花括号把函数名和参数括起。
感觉很像一个变量,是不是?
函数中的参数可以使用变量,为了风格的统一,函数和变量的括号最好一样,如使用“$(subst
a,b,$(x))”这样的形式,而不是“$(substa,b,${x})”的形式。
因为统一会更清楚,也会减少一些不必要的麻烦。
还是来看一个示例:
comma:
=,
empty:
=
space:
=$(empty)$(empty)
foo:
=abc
bar:
=$(subst$(space),$(comma),$(foo))
在这个示例中,$(comma)的值是一个逗号。
$(space)使用了$(empty)定义了一个空格,$(foo)的值是“abc”,$(bar)的定义用,调用了函数“subst”,这是一个替换函数,这个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数是替换操作作用的字串。
这个函数也就是把$(foo)中的空格替换成逗号,所以$(bar)的值是“a,b,c”。
二、字符串处理函数
1.$(substFROM,TO,TEXT)
函数名称:
字符串替换函数—subst。
函数功能:
把字串“TEXT”中的“FROM”字符替换为“TO”。
返回值:
替换后的新字符串。
2.$(patsubstPATTERN,REPLACEMENT,TEXT)
函数名称:
模式替换函数—patsubst。
函数功能:
搜索“TEXT”中以空格分开的单词,将否符合模式“TATTERN”替换为“REPLACEMENT”。
参数“PATTERN”中可以使用模
式通配符“%”来代表一个单词中的若干字符。
如果参数“REPLACEMENT”中也包含一个“%”,那么“REPLACEMENT”中的“%”将是
“TATTERN”中的那个“%”所代表的字符串。
在“TATTERN”和“REPLACEMENT”中,只有第一个“%”被作为模式字符来处理,后续的作为字符本上来处理。
在两个参数中当使用第一个“%”本是字符本身时,可使用反斜杠“\”对它进行转义处理。
返回值:
替换后的新字符串。
函数说明:
参数“TEXT”单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。
3.$(stripSTRINT)
函数名称:
去空格函数—strip。
函数功能:
去掉字串(若干单词,使用若干空字符分割)“STRINT”开头和结尾的空字符,并将其中多个连续空字符合并为一个空字符。
返回值:
无前导和结尾空字符、使用单一空格分割的多单词字符串。
函数说明:
空字符包括空格、[Tab]等不可显示字符。
4.$(findstringFIND,IN)
函数名称:
查找字符串函数—findstring。
函数功能:
搜索字串“IN”,查找“FIND”字串。
返回值:
如果在“IN”之中存在“FIND”,则返回“FIND”,否则返回空。
函数说明:
字串“IN”之中可以包含空格、[Tab]。
搜索需要是严格的文本匹配。
5.$(filterPATTERN…,TEXT)
函数名称:
过滤函数—filter。
函数功能:
过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。
可以使用多个模式。
模式中一般需要包含模式字符“%”。
存在多个模式时,模式表达式之间使用空格分割。
返回值:
空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。
函数说明:
“filter”函数可以用来去除一个变量中的某些字符串,我们下边的例子中就是用到了此函数。
6.$(filter-outPATTERN...,TEXT)
函数名称:
反过滤函数—filter-out。
函数功能:
和“filter”函数实现的功能相反。
过滤掉字串“TEXT”中所有符合模式“PATTERN”的单词,保留所有不符合此模式的单词。
可以有多个模式。
存在多个模式时,模式表达式之间使用空格分割。
。
返回值:
空格分割的“TEXT”字串中所有不符合模式“PATTERN”的字串。
函数说明:
“filter-out”函数也可以用来去除一个变量中的某些字符串,(实现和“filter”函数相反)。
7.$(sortLIST)
函数名称:
排序函数—sort。
函数功能:
给字串“LIST”中的单词以首字母为准进行排序(升序),并取掉重复的单词。
返回值:
空格分割的没有重复单词的字串。
函数说明:
两个功能,排序和去字串中的重复单词。
可以单独使用其中一个功能。
8.$(wordN,TEXT)
函数名称:
取单词函数—word。
函数功能:
取字串“TEXT”中第“N”个单词(“N”的值从1开始)。
返回值:
返回字串“TEXT”中第“N”个单词。
函数说明:
如果“N”值大于字串“TEXT”中单词的数目,返回空字符串。
如果“N”为0,出错!
9.$(wordlistS,E,TEXT)
函数名称:
取字串函数—wordlist。
函数功能:
从字串“TEXT”中取出从“S”开始到“E”的单词串。
“S”和“E”表示单词在字串中位置的数字。
返回值:
字串“TEXT”中从第“S”到“E”(包括“E”)的单词字串。
函数说明:
“S”和“E”都是从1开始的数字。
当“S”比“TEXT”中的字数大时,返回空。
如果“E”大于“TEXT”字数,返回从“S”开始,到“TEXT”结束的单词串。
如果“S”大于“E”,返回空。
10.$(wordsTEXT)
函数名称:
统计单词数目函数—words。
函数功能:
字算字串“TEXT”中单词的数目。
返回值:
“TEXT”字串中的单词数。
11.$(firstwordNAMES…)
函数名称:
取首单词函数—firstword。
函数功能:
取字串“NAMES…”中的第一个单词。
返回值:
字串“NAMES…”的第一个单词。
函数说明:
“NAMES”被认为是使用空格分割的多个单词(名字)的序列。
函数忽略“NAMES…”中除第一个单词以外的所有的单词。
三、文件名处理函数
下面我们要介绍的函数主要是处理文件名的。
每个函数的参数字符串都会被当做一个或是一系列的文件名来对待。
1、$(wildcard)
名称:
文件名展开函数——wildcard。
功能:
功能是展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。
返回:
函数返回展开后的文件名列表。
示例:
$(wildcard*.c)
返回结果是一个所有以'.c'结尾的文件的列表。
2、$(dir)
名称:
取目录函数——dir。
功能:
从文件名序列中取出目录部分。
目录部分是指最后一个反斜杠(“/”)之前的部分。
如果没有反斜杠,那么返回“./”。
返回:
返回文件名序列的目录部分。
示例:
$(dirsrc/foo.chacks)返回值是“src/
./”。
3、$(notdir)
名称:
取文件函数——notdir。
功能:
从文件名序列中取出非目录部分。
非目录部分是指最后一个反斜杠(“/”)之后的部分。
返回:
返回文件名序列的非目录部分。
示例:
$(notdirsrc/foo.chacks)返回值是“foo.c
hacks”。
4、$(suffix)
名称:
取后缀函数——suffix。
功能:
从文件名序列中取出各个文件名的后缀。
返回:
返回文件名序列的后缀序列,如果文件没有后缀,则返回空字串。
示例:
$(suffixsrc/foo.csrc-1.0/bar.chacks)返回值是“.c
.c”。
5、$(basename)
名称:
取前缀函数——basename。
功能:
从文件名序列中取出各个文件名的前缀部分。
返回:
返回文件名序列的前缀序列,如果文件没有前缀,则返回空字串。
示例:
$(basenamesrc/foo.csrc-1.0/bar.chacks)返回值是“src/foo
src-1.0/barhacks”。
6、$(addsuffix,)
名称:
加后缀函数——addsuffix。
功能:
把后缀加到中的每个单词后面。
返回:
返回加过后缀的文件名序列。
示例:
$(addsuffix.c,foobar)返回值是“foo.c
bar.c”。
7、$(addprefix,)
名称:
加前缀函数——addprefix。
功能:
把前缀加到中的每个单词后面。
返回:
返回加过前缀的文件名序列。
示例:
$(addprefixsrc/,foobar)返回值是“src/foo
src/bar”。
8、$(join,)
名称:
连接函数——join。
功能:
把中的单词对应地加到的单词后面。
如果的单词个数要比的多,那么,中的多出来的单词将保持原样。
如果的单词个数要比多,那么,多出来的单词将被复制到中。
返回:
返回连接过后的字符串。
示例:
$(joinaaabbb,111222333)返回值是“aaa111
bbb222333”。
四、foreach函数
foreach函数和别的函数非常的不一样。
因为这个函数是用来做循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell(/bin/sh)中的for语句,或是C-Shell(/bin/csh)中的foreach语句而构建的。
它的语法是:
$(foreach
,)
这个函数的意思是,把参数中的单词逐一取出放到参数所指定的变量中,然后再执行所包含的表达式。
每一次会返回一个字符串,循环过程中,的所返回的每个字符串会以空格分隔,最后当整个循环结束时,所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
所以,最好是一个变量名,可以是一个表达式,而中一般会使用这个参数来依次枚举中的单词。
举个例子:
names:
=abcd
files:
=$(foreachn,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.ob.oc.od.o”。
注意,foreach中的参数是一个临时的局部变量,foreach函数执行完后,参数的变量将不在作用,其作用域只在foreach函数当中。
五、if函数
if函数很像GNU的make所支持的条件语句——ifeq(参见前面所述的章节),if函数的语法是:
$(if,)
或是
$(if
,)
可见,if函数可以包含“else”部分,或是不含。
即if函数的参数可以是两个,也可以是三个。
参数是if的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,会被计算,否则会被计算。
而if函数的返回值是,如果为真(非空字符串),那个会是整个函数的返回值,如果为假(空字符串),那么会是整个函数的返回值,此时如果没有被定义,那么,整个函数返回空字串。
所以,和只会有一个被计算。
六、call函数
call函数是唯一一个可以用来创建新的参数化的函数。
你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。
其语法是:
$(call
,,...)
当make执行这个函数时,参数中的变量,如$
(1),$
(2),$(3)等,会被参数,,依次取代。
而的返回值就是call函数的返回值。
例如:
reverse=$
(1)$
(2)
foo=$(callreverse,a,b)
那么,foo的值就是“ab”。
当然,参数的次序是可以自定义的,不一定是顺序的,如:
reverse=
$
(2)$
(1)
foo=$(callreverse,a,b)
此时的foo的值就是“ba”。
七、origin函数
origin函数不像其它的函数,他并不操作变量的值,他只是告诉你你的这个变量是哪里来的?
其语法是:
$(origin)
注意,是变量的名字,不应该是引用。
所以你最好不要在中使用“$”字符。
Origin函数会以其返回值来告诉你这个变量的“出生情况”,下面,是origin函数的返回值:
“undefined”
如果从来没有定义过,origin函数返回这个值“undefined”。
“default”
如果是一个默认的定义,比如“CC”这个变量,这种变量我们将在后面讲述。
“environment”
如果是一个环境变量,并且当Makefile被执行时,“-e”参数没有被打开。
“file”
如果这个变量被定义在Makefile中。
“command
line”
如果这个变量是被命令行定义的。
“override”
如果是被override指示符重新定义的。
“automatic”
如果是一个命令运行中的自动化变量。
关于自动化变量将在后面讲述。
这些信息对于我们编写Makefile是非常有用的,例如,假设我们有一个Makefile其包了一个定义文件Make.def,在Make.def中定义了一个变量“bletch”,而我们的环境中也有一个环境变量“bletch”,此时,我们想判断一下,如果变量来源于环境,那么我们就把之重定义了,如果来源于Make.def或是命令行等非环境的,那么我们就不重新定义它。
于是,在我们的Makefile中,我们可以这样写:
ifdefbletch
ifeq"$(originbletch)"
"environment"
bletch=barf,gag,etc.
endif
endif
当然,你也许会说,使用override关键字不就可以重新定义环境中的变量了吗?
为什么需要使用这样的步骤?
是的,我们用override是可以达到这样的效果,可是override过于粗暴,它同时会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不想重新定义命令行传来的。
八、shell函数
shell函数也不像其它的函数。
顾名思义,它的参数应该就是操作系统Shell的命令。
它和反引号“`”是相同的功能。
这就是说,shell函数把执行操作系统命令后的输出作为函数返回。
于是,我们可以用操作系统命令以及字符串处理命令awk,sed等等命令来生成一个变量,如:
contents:
=$(shellcatfoo)
files:
=$(shellecho*.c)
注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。
特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多。