Makefile函数

在Makefile中可以使用函数来处理文本,从而让我们的命令或是规则更为灵活和智能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返回值可以当做变量来使用。

1.函数调用语法

$(<function> <arguments>)
#或
${<function> <arguments>}

函数调用以$开头,以圆括号或花括号把函数名和参数括起,像是对一个变量的引用,函数中的参数可以使用变量。其中<function>为函数名,<arguments>为函数参数,又空白符(空格、Tab)分隔,如果有多个参数,则使用逗号隔开。

为了统一风格,建议函数和变量统一使用花括号,如使用$(subst a,b,$(x))这样的形式,而不是$(subst a,b,${x})的形式。

2.字符串替换与分析函数

2.1 subst

原型:

$(subst <from>,<to>,<text>)

功能:将字符串text中的from变为to。

示例:

$(subst ee,EE,feet on the street)

返回 fEEt on the strEEt。

2.2 patsubst

原型:

$(patsubst  <pattern>,<replacement>,<text>)

功能:查找<text>中以空白符(空格、Tab)分隔的单词是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符%,表示任意长度的字串。如果<replacement>中也包含%,那么,<replacement>中的这个%将是<pattern>中的那个%所代表的字串。可以用反斜杠\来转义,即\%来表示真实含义的%字符。返回:函数返回被替换过后的字符串。

示例:

$(patsubst %.c,%.o,x.c.c bar.c)

把字串“x.c.c bar.c”符合模式%.c的单词替换成%.o,返回结果是“x.c.o bar.o”。

2.3 strip

原型:

$(strip <string>)

功能:去掉string字符串中开头和结尾的空白字符(空格、Tab)。

示例:

$(strip a b c )

把字串“a b c ”去到开头和结尾的空格,结果是“a b c”。

2.4 findstring

原型:

$(findstring <FIND>,<IN>) 

功能:从字符串<IN>中查找指定的字符串<FIND>,找到返回<FIND>,找不到返回空。

示例:

$(findstring a,a b c) 
$(findstring a,b c) 

第一个函数结果是字符串是“a”,第二个返回空字符。

2.5 filter

原型:

$(filter <pattern...>,<text>)

功能:以<pattern> 模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词。可以有多个模式。

示例:

sources := foo.c bar.c baz.s ugh.h
result := $(filter %.c %.s,${sources})

result 是“foo.c bar.c baz.s”。

2.6 filter-out

原型:

$(filter-out <pattern...>,<text>)

功能:以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词。可以有多个模式。

示例:

objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
result := $(filter-out $(mains),$(objects)) 

result 是“foo.o bar.o”。

2.7 sort

原型:

$(sort <list> )

功能:给字符串<list>中的单词排序(升序)。注意:sort函数会去掉<list>中相同的单词

示例:

$(sort foo bar lose)

返回"bar foo lose" 。

2.8 word

原型:

$(word <n>,<text>)

功能:取字符串<text>中第<n>个单词。下标从1开始,如果比中的单词数要大,那么返回空 字符串。

示例:

$(word 2, foo bar baz)

返回 bar。

2.9 wordlist

原型:

$(wordlist <s>,<e>,<text> )

功能:从字符串<text>中取从<s>开始到<e>的单词串。<s><e>是一个数字下标,下标从1开始。如果<s><text>中的单词数要大,那么返回空字符串。如果<e>大于<text>的单词数,那么返回从<s>开始,到<text>结束的单词串。

示例:

$(wordlist 2, 3, foo bar baz)。

返回"bar baz"。

2.10 words

原型:

$(words <text> )

功能:统计字符串<text>中的单词个数。

示例:

$(words, foo bar baz)

返回3。

备注:如果我们要取<text>中最后的一个单词,可以这样:$(word $(words <text> ),<text> )

2.11 firstword

原型:

$(firstword <word...>)

其中word…为多个空格分隔的单词。

功能:取word…中的第一个单词。

示例:

$(firstword a b c)

返回 a。

2.12 lastword

函数原型:

 $(lastword <word...>)

其中word…为多个空白符(空格、Tab)分隔的单词。

功能:作用与firstword函数相反,取word…中的最后一个单词。

示例:

$(firstword a b c)

返回 c。

3.文件名称处理函数

3.1 dir

原型:

$(dir <names...>)

作用:从多个以空白符分隔的文件列表中获取文件目录。目录部分是指最后一个反斜杠/之 前的部分。如果没有反斜杠,那么返回“./”。 示例:

$(dir src/foo.c hacks)

返回"src ./"。

3.2 notdir

原型:

$(notdir <names...>)

功能:从多个以空白符分隔的文件列表中获取非目录部分。非目录部分是指最后一个反斜杠/之后的内容。 示例:

 $(notdir src/foo.c hacks)

返回"foo.c hacks"。

3.3 suffix

原型:

$(suffix <names…>)

功能:文件名序列<names>中取出各个文件名的后缀。如果文件没有后缀,则返回空字串。

示例:

$(suffix src/foo.c src-1.0/bar.c hacks)

返回".c .c"。

3.4 basename

原型:

$(basename  <names...>)

功能:从文件名序列<names>中取出各个文件名的前缀部分。如果文件没有前缀,则返回空字串。

示例:

$(basename src/foo.c src-1.0/bar.c hacks)

返回"src/foo src-1.0/bar hacks”。

3.5 addsuffix

原型:

$(addsuffix <suffix>,<names...> )

功能:把后缀<suffix>加到<names>中的每个单词后面。

示例:

$(addsuffix .c,foo bar)

返回"foo.c bar.c"。

3.6 addprefix

原型:

$(addprefix <prefix>,<names...> )

功能:把前缀加到中的每个单词后面。

示例:

$(addprefix src/,foo bar)

返回值是"src/foo src/bar"。

3.7 join

原型:

$(join <list1>,<list2> )

功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数与比< list2>不同,则原样输出。

示例:

res1 = $(join a b,.c .cpp .go)
res2 = $(join a b c,.c .cpp)

res1 是"a.c b.cpp .go",res2是"a.c b.cpp c"。

3.8 wildcard

原型:

$(wildcard <pattern...>)

功能:扩展通配符函数用于获取匹配此模式的所有文件列表,文件名以空格分隔。如果不存在任何符合此模式的文件,返回空。 示例:

$(wildcard *.cpp *.c)

返回make工作目录下的所有以.cpp和.c为后缀的文件名。

4.make控制函数

make控制函数make运行的方式。通常,它们用于向生成文件的用户提供信息,或者在检测到某种环境错误时使make停止。

4.1 info

原型:

$(info <text>)

作用:向标准输出打印文本<text>,用于输出调试信息。 示例:

$(info some debug info)

标准输出打印some debug info。

4.2 warning

原型:

$(warning <info>)

功能:向标准输出打印文本<text>,用于输出警告信息。make继续执行。

示例:

$(warning some warning info)

标准输出打印some warning info。

4.3error

原型:

$(error <text>)

功能:向标准错误输出打印文本<text>,用于输出指明错误信息。make停止执行。

示例:

ERROR="can't find commad g++"
ifdef ERROR
$(error error is $(ERROR1))
endif

因为ERROR值非空,所以输出错误信息如下错误信息,并停止make的执行。

makefile:3: *** error is "can't find commad g++".  Stop.

5.其它函数

5.1 foreach

原型:

$(foreach <var>,<list>,<text>)

功能:把参数list中的单词逐一取出放到参数var所指定的变量中,然后再执行text所包含的表达式。每一次text会返回一个字符串,循环过程中,text的所返回的每个字符串会以空格分隔,最后当整个循环结束时,text所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。

所以,var是一个变量名,list是一个元素列表,而text中会使用var这个参数依次枚举list中的元素。

示例:

names := a b c d
files := $(foreach n,${names},$(n).o)

files的结果为“a.o b.o c.o d.o”。

5.2 call

原型:

$(call <expression>,<parm1>,<parm2>,<parm3>,...)

功能:call函数是唯一一个可以用来创建新的参数化函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。当make执行call函数时,自定义表达式expression中的参数,如$(1),$(2),$(3)等,会被参数<parm1>,<parm2>,<parm3>依次取代。expression的返回值就是call函数的返回值。

示例:

reverse = $(1) $(2)
foo = $(call reverse,a,b)

foo的值是"a b"。当然,参数的次序是可以自定义的,不一定是顺序的,如:

reverse = $(2) $(1)
foo = $(call reverse,a,b)

此时的 foo 的值就是"b a"。

5.3 eval

原型:

 $(eval <text>)

功能:eval 函数是一个比较特殊的函数,其将<text>作为 makefile 的一部分而被 make 解析执行。

返回值:eval 函数的返回值时空,也可以说没有返回值。

注意:该函数在执行时会对它的参数进行两次展开,第一次展开是由 eval 函数本身完成,第二次是函数展开后的结果被作为 makefile 内容时由 make 解析时展开。

示例: 假设有以下makefile。

define MA
ALL:
        @echo hello world
endef

$(info $(MA))
$(info ----------------------)
$(eval $(MA))

执行make命令将会输出如下内容:

ALL:
	@echo hello world
----------------------
hello world

可以看出,$(eval $(MA))的执行相当于make命令执行了如下指令:

ALL:
        @echo hello world

即执行Shell命令echo hello world

5.4 shell

原型:

$(shell <shell_command>)

功能:shell函数也不像其它的函数。顾名思义,它的参数是操作系统的Shell命令,shell函数把执行Shell命令后的输出作为函数返回。 示例:

$(shell cat foo)

返回 foo。


参考文献

[1]Makefile经典教程(掌握这些足够) [2]GNU make manual

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券