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 停止。

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.3 error

  • 原型
$(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 函数本身完成,第二次是函数展开后的结果作为 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值