函数(七)

本文详细介绍了Makefile中的函数用法,包括函数调用语法、字符串操作函数、文件名操作函数、条件函数、foreach函数等。通过对函数的掌握,可以更好地在Makefile中处理文本、计算文件、执行recipe,提高自动化构建的效率。
摘要由CSDN通过智能技术生成

8 函数

函数允许你在makefile中处理文本,用于计算文件,操作和执行recipes。在函数调用中提供函数名和函数操作的参数。函数处理的结果替换到函数在makefile中调用的位置,就像变量被替换一样。

8.1 函数调用语法

函数调用类似于变量引用。它可以出现在任何变量引用可以出现的地方,使用与变量引用同样的扩展规则。函数调用语法如下:

$(function arguments)

或者:

${function arguments}

这里function是函数名,是make函数列表中的一个。可以使用call创建自己的函数。

arguments表示函数的参数,与函数名用若干空格或tab隔开,如果有多个参数,用逗号隔开。空格和逗号不是参数值的一部分。函数调用时两边的分隔符(圆括号或花括号)只能成对出现在变量中,其它种类的分隔符可以单独出现。如果参数中包含其它的函数调用或变量引用,最好使用相同种类的分隔符,例如,写成$(subst a,b,$(x)),而不是$(subst a,b,${x})。这样更清晰,因为只有一种类型的分隔符需要被匹配。

写作参数的文本通过变量和函数调用处理,最终生成参数的值,也就是函数操作的文本。替换的顺序和参数出现的顺序一致。

逗号、未配对的圆括号或花括号不可以出现在参数文本中,前导空格不可以当作第一个参数文本的一部分。这些字符通过变量替换放到参数值当中。下面例子中,前面定义的变量commaspace,它们的值分别是逗号和空格字符,然后需要这些字符的地方,使用这两个变量替换即可:

comma:= ,
empty:= 
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# bar is now 'a,b,c'

这里subst函数替换foo中每个空格为逗号,并返回替换结果。

8.2 字符串操作函数

下面是一些操作字符串的函数:

  • $(subst from,to,text)

    实现对text的文本替换:每个在text中的from都替换成to。结果是替换后的字符串,例如:

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

    结果为fEEt on the strEEt

  • $(patsubst pattern,replacement,text)

    查找text中用空格分隔的匹配pattern模板的单词,并用replacement替换之。这里pattern可能包含%通配符,匹配一个单词的任意多个任意字符。如果replacement中也包含%,那这个%pattern中匹配的部分替换。只有patternreplacement中的第一个%会被当作通配符,之后的%表示字符本身。
    patsubst函数调用中,%字符可以使用\引用。反斜杆\也可以引用反斜杆本身。当比较文件名或进行词干替换之前,作为引用字符的\会被移除。例如,模板the\%weird\\%pattern\\使用通配符%分割为the%weird\pattern\\两部分。最后两个反斜杆被保留,因为它们不能影响%字符。
    单词之间的空格被视为一个空格,开头和结尾的空格被忽略。
    例如:

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

    结果为x.c.o bar.o

    $(var:pattern=replacement)
    

    等效于:

    $(patsubst pattern,replacement,$(var))
    

    第二个简化patsubst的一个普遍用法是替换文件的后缀:

    $(var:suffix=replacement)
    

    等效于:

    $(patsubst %suffix,%replacement,$(var))
    

    例如,有一个objects文件列表:

    objects = foo.o bar.o baz.o
    

    为获得对应的源文件列表,可以写作:

    $(objects:.o=.c)
    

    而不是:

    $(patsubst %.o,%.c,$(objects))
    
  • $(strip string)

    用来移除字符串开头和结尾的空格,并且字符串中的的连续多个空格会替换为一个。因此,$(strip a b c )结果为'a b c'
    函数strip在连接条件指令时非常有用。当使用ifeqifneq将字符串与空字符串''比较时,你通常想让只包含空格的字符串作为空字符串。
    因此,下面的语句可能得不到想要的结果:

    .PHONY: all
    ifneq "$(needs_made)" ""
    all: $(needs_made)
    else
    all:;@echo 'Nothing to make!'
    endif
    

    ifneq指令中的变量引用$(needs_made)替换为函数调用$(strip $(needs_made)),会使程序更健壮。

  • $(findstring find,in)

    in中查找find。如果找到,返回find,否则结果为空。你可以在条件测试中使用这个函数判断给定字符串中是否包含一个特定子字符串。下面两个例子:

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

    分别返回'a'''

  • $(filter pattern...,text)

    返回text中用空格分隔的所有匹配pattern的单词,删除所有不匹配的单词。pattern使用通配符%,就像函数patsubst中一样。
    函数filter可以用于分离变量中不同类型的字符串(比如文件名)。例如:

    sources := foo.c bar.c baz.s ugh.h
    foo: $(sources)
            cc $(filter %.c %.s,$(sources)) -o foo
    

    表示foo基于文件foo.cbar.cbaz.sugh.h,但是在编译时只使用foo.cbar.cbaz.s

  • $(filter-out pattern...,text)

    返回text中所有不匹配pattern的以空格分隔的单词,删除所有匹配的单词。相对于函数filter
    例如,给定:

    objects=main1.o foo.o main2.o bar.o
    mains=main1.o main2.o
    

    下面的语句生成一个不包含mains中文件的所有objects文件列表:

    $(filter-out $(mains),$(objects))
    
  • $(sort list)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值