Makefile中常用到的函数总结

目录

一、字符串操作函数 

1.字符串处理函数 subst

2.模式字符串替换函数 patsubst 

3.去空格函数 strip

4.查找字符串函数 findstring

5.过滤函数 filter

6.反过滤函数 filter-out

7.排序函数 sort

8.取单词函数 word

 9.取单词串函数 wordlist

10.单词个数统计函数 words

11.首单词函数 firstword

二、文件名操作函数

1.取目录函数 dir

2.取文件函数 notdir

3.取后缀函数 suffix

4.取前缀函数 basename

5.加后缀函数 addsuffix

6.连接函数 join

三、foreach 函数

四、call函数

五、origin函数

六、shell函数

七、控制make的函数


 

一、字符串操作函数 

1.字符串处理函数 subst

英文中sub有替补的意思,subst的函数形式

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

名称:字符串替换函数——subst
功能:把字串<text>中的<from>字符串替换成<to>
返回:函数返回被替换过后的字符串。

举例:

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

返回值为:(将ee替换为EE)

 fEEt on the strEEt

2.模式字符串替换函数 patsubst 

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

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

举例:

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

返回结果是x.c.o bar.o

将字串x.c.c bar.c符合模式%.c的单词替换成%.o

3.去空格函数 strip

$(strip <string>)

名称:去空格函数——strip
功能:去掉<string>字串中开头和结尾的空字符。
返回:返回被去掉空格的字符串值。

举例:

$(strip     a b c     )

把字串a b c去到开头和结尾的空格,返回结果是a b c

4.查找字符串函数 findstring

$(findstring <find>,<in>)

名称:查找字符串函数——findstring
功能:在字串<in>中查找<find>字串。
返回:如果找到,那么返回<find>,否则返回空字符串。

举例:

$(findstring a,a b c)

返回a字符串

$(findstring a,b c)

返回“”字符串(空字符串)

5.过滤函数 filter

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

名称:过滤函数——filter
功能:以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词。可以有多个模式。
返回:返回符合模式<pattern>的字串。

 举例:

sources := foo.c bar.c baz.s ugh.h

foo: $(sources) cc

$(filter %.c %.s,$(sources)) -o foo

$(filter %.c %.s,$(sources))返回的值是foo.c bar.c baz.s

6.反过滤函数 filter-out

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

名称:反过滤函数——filter-out
功能:以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词。可以有多个模式。
返回:返回不符合模式<pattern>的字串。

 举例:

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

mains=main1.o main2.o

$(filter-out $(mains),$(objects))

返回值是`foo.o bar.o``

7.排序函数 sort

$(sort <list>)

名称:排序函数——sort
功能:给字符串<list>中的单词排序(升序)。
返回:返回排序后的字符串。

sort函数会去掉<list>中相同的单词。

举例:

$(sort foo bar lose)

返回值为: bar foo lose

$(sort foo bar lose foot)

返回值为:bar foo foot lose

$(sort foo bar lose foo)

返回值为: bar foo lose   #去掉了相同的单词

8.取单词函数 word

$(word <n>,<text>)

名称:取单词函数——word
功能:取字符串<text>中第<n>个单词。(从一开始)
返回:返回字符串<text>中第<n>个单词。如果<n><text>中的单词数要大,那么返回空字符串。

举例:

$(word 2, foo bar baz)

返回值是bar

 9.取单词串函数 wordlist

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

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

举例:

$(wordlist 2, 3, foo bar baz)

返回值是bar baz

10.单词个数统计函数 words

$(words <text>)

名称:单词个数统计函数——words
功能:统计<text>中字符串中的单词个数。
返回:返回<text>中的单词数。

举例:

$(words, foo bar baz)

返回值是3

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

text = foo bar baz

$(word $(words $(text)),$(text))

返回值 baz

11.首单词函数 firstword

$(firstword <text>)

名称:首单词函数——firstword
功能:取字符串<text>中的第一个单词。
返回:返回字符串<text>的第一个单词。

举例:

$(firstword foo bar)

返回值是foo

也函数可以用word函数来实现:$(word 1,<text>)

二、文件名操作函数

1.取目录函数 dir

$(dir <names...>)

名称:取目录函数——dir
功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(/)之前的部分。如果没有反斜杠,那么返回./
返回:返回文件名序列<names>的目录部分。

举例:

$(dir src/foo.c hacks)

返回值是src/ ./

2.取文件函数 notdir

$(notdir <names...>)

名称:取文件函数——notdir
功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(/)之后的部分。
返回:返回文件名序列<names>的非目录部分。

举例:

$(notdir src/foo.c hacks)

返回值是foo.c hacks

3.取后缀函数 suffix

$(suffix <names...>)

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

举例:

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

返回值是.c .c

4.取前缀函数 basename

$(basename <names...>)

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

举例:

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

返回值是src/foo src-1.0/bar hacks

5.加后缀函数 addsuffix

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

名称:加后缀函数——addsuffix
功能:把后缀<suffix>加到<names>中的每个单词后面。
返回:返回加过后缀的文件名序列。

举例:

$(addsuffix .c,foo bar)

返回值是foo.c bar.c

6.连接函数 join

$(join <list1>,<list2>)

名称:连接函数——join
功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中。
返回:返回连接过后的字符串

举例:

$(join aaa bbb , 111 222 333)

返回值是aaa111 bbb222 333

三、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)

$(name)中的单词会被挨个取出,并存到变量n中,$(n).o每次根据$(n)计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是a.o b.o c.o d.o

四、call函数

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

call函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。

make执行这个函数时,<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

五、origin函数

$(origin <variable>)

他并不操作变量的值,他只是告诉你你的这个变量是哪里来的?

<variable>是变量的名字,不应该是引用。所以你最好不要在<variable>中使用$字符。Origin函数会以其返回值来告诉你这个变量的“出生情况”

下面,是origin函数的返回值:

  • undefined
    如果从来没有定义过,origin函数返回这个值undefined
  • default
    如果<variable>是一个默认的定义,比如CC这个变量,这种变量我们将在后面讲述。
  • environment
    如果<variable>是一个环境变量,并且当Makefile被执行时,-e参数没有被打开。
  • file
    如果<variable>这个变量被定义在Makefile中。
  • command line
    如果<variable>这个变量是被命令行定义的。
  • override
    如果<variable>是被override指示符重新定义的。
  • automatic
    如果<variable>是一个命令运行中的自动化变量。关于自动化变量将在后面讲述。

这些信息对于我们编写Makefile是非常有用的,例如,假设我们有一个Makefile其包了一个定义文件Make.def,在Make.def中定义了一个变量bletch,而我们的环境中也有一个环境变量bletch,此时,我们想判断一下,如果变量来源于环境,那么我们就把之重定义了,如果来源于Make.def或是命令行等非环境的,那么我们就不重新定义它。于是,在我们的Makefile中,我们可以这样写:

ifdef bletch

ifeq "$(origin bletch)" "environment"

bletch = barf, gag, etc.

endif

endif

当然,你也许会说,使用override关键字不就可以重新定义环境中的变量了吗?为什么需要使用这样的步骤?是的,我们用override是可以达到这样的效果,可是override过于粗暴,它同时会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不想重新定义命令行传来的。

六、shell函数

它的参数应该就是操作系统Shell的命令。它和反引号`是相同的功能。这就是说,shell函数把执行操作系统命令后的输出作为函数返回。于是,我们可以用操作系统命令以及字符串处理命令awksed等等命令来生成一个变量,如:

contents := $(shell cat foo)

files := $(shell echo *.c)

注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多。

七、控制make的函数

make提供了一些函数来控制make的运行。通常,你需要检测一些运行Makefile时的运行时信息,并且根据这些信息来决定,你是让make继续执行,还是停止。

$(error <text ...>)

产生一个致命的错误,<text ...>是错误信息。注意,error函数不会在一被使用就会产生错误信息,所以如果你把其定义在某个变量中,并在后续的脚本中使用这个变量,那么也是可以的。例如:
示例一:

ifdef ERROR_001

$(error error is $(ERROR_001))

endif

示例二:

ERR = $(error found an error!)

.PHONY: err

err: ; $(ERR)

示例一会在变量ERROR_001定义了后执行时产生error调用,而示例二则在目录err被执行时才发生error调用。

$(warning <text ...>)

这个函数很像error函数,只是它并不会让make退出,只是输出一段警告信息,而make继续执行

注:本文是根据陈皓,文章来源于他的优快云专栏(1条消息) 编程语言_haoel的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值