以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。
函数的调用和变量的调用很像。引用变量的格式为
$(变量名)
,而函数调用的格式如下:
$(<function> <arguments>) 或者是 ${<function> <arguments>}
- function 是函数名,arguments 是函数的参数。
- 参数之间要用逗号分隔开。
- 参数和函数名之间使用空格分开。
- 调用函数的时候要使用字符“$”,后面可以跟小括号或者大括号。
建议用小括号,这样就可以记成:无论是调用函数还是引用变量,Makefile中都是用小括号,Shell中都是使用花括号。但Shell中将命令的结果赋给变量时也会使用小括号,比如 variable=$(command)。而Shell函数,见博客Shell函数_天糊土的博客-CSDN博客。
函数使用格式如下:
$(patsubst <pattern>,<replacement>,<text>)
函数说明:查找 text 中的单词是否符合模式 pattern,如果匹配的话,则用 replacement 替换。返回值为替换后的新字符串。
实例:
OBJ=$(patsubst %.c,%.o,1.c 2.c 3.c) all: @echo $(OBJ)执行 make 命令,我们可以得到的值是 "1.o 2.o 3.o",这些都是替换后的值。
函数使用格式如下:
$(subst <from>,<to>,<text>)
函数说明:把字符串中的 form 替换成 to,返回值为替换后的新字符串。
实例:
OBJ=$(subst ee,EE,feet on the street) all: @echo $(OBJ)执行 make 命令,我们得到的值是“fEEt on the strEEt”。
函数使用格式如下:
$(strip <string>)
函数说明:去掉字符串的开头和结尾的字符串,并且将其中的多个连续的空格合并成为一个空格。返回值为去掉空格后的字符串。
实例:
OBJ=$(strip a b c) all: @echo $(OBJ)执行完 make 之后,结果是“a b c”。这个只是除去开头和结尾的空格字符,并且将字符串中的空格合并成为一个空格。
函数使用格式如下:
$(findstring <find>,<in>)
函数说明:查找 in 中的 find ,如果查找的目标字符串存在,则返回目标字符串,否则返回空。
实例:
OBJ=$(findstring a,a b c) all: @echo $(OBJ)执行 make 命令,得到的返回的结果就是 "a"。
函数使用格式如下:
$(filter <pattern>,<text>)
函数说明:过滤出 text 中符合模式 pattern 的字符串,可以有多个 pattern 。返回值为过滤后的字符串。
实例:
OBJ=$(filter %.c %.o,1.c 2.o 3.s) all: @echo $(OBJ)执行 make 命令,我们得到的值是“1.c 2.o”。
函数使用格式如下:
$(filter-out <pattern>,<text>)
函数说明:功能和 filter 函数正好相反,但是用法相同。去除符合模式 pattern 的字符串,保留符合的字符串。返回值是保留的字符串。
实例:
OBJ=$(filter-out 1.c 2.o ,1.o 2.c 3.s) all: @echo $(OBJ)执行 make 命令,打印的结果是“3.s”。
函数使用格式如下:
$(sort <list>)
函数说明:将
<list>
中的单词排序(升序)。返回值为排列后的字符串。实例:
OBJ=$(sort foo bar foo lost) all: @echo $(OBJ)执行 make 命令,我们得到的值是“bar foo lost”。注意:sort会去除重复的字符串。
函数使用格式如下:
$(word <n>,<text>)
函数说明:取出函数
<text>
中的第n个单词。返回值为我们取出的第 n 个单词。实例:
OBJ=$(word 2,1.c 2.c 3.c) all: @echo $(OBJ)执行 make 命令,得到的值是“2.c”。
在编写 Makefile 的时候,很多情况下需要对文件名进行操作。例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等。当遇到这样的问题的时手动修改是不太可能的,因为文件可能会很多,而且 Makefile 中操作文件名可能不止一次。所以 Makefile 提供了相应的函数来实现文件名的操作。
注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待。
函数使用格式如下:
$(dir <names>)
函数说明:函数的功能是从文件名序列 names 中取出目录部分,如果 names 中没有 "/" ,取出的值为 "./" 。返回值为目录部分,指的是最后一个反斜杠之前的部分。如果没有反斜杠将返回“./”。
实例:
OBJ=$(dir src/foo.c hacks) all: @echo $(OBJ)执行 make 命令,得到的值是“src/ ./”。提取文件 foo.c 的路径是 "/src" 和文件 hacks 的路径 "./"。
函数使用格式如下:
$(notdir <names>)
函数说明:函数的功能是从文件名序列 names 中取出非目录的部分。非目录的部分是最后一个反斜杠之后的部分。返回值为文件非目录的部分。
实例:
OBJ=$(notdir src/foo.c hacks) all: @echo $(OBJ)执行 make 命令,我们可以得到的值是“foo.c hacks”。
函数使用格式如下:
$(suffix <names>)
函数说明:从文件名序列中 names 中取出各个文件的后缀名。返回值为文件名序列 names 中的后缀序列,如果文件没有后缀名,则返回空字符串。
实例:
OBJ=$(suffix src/foo.c hacks) all: @echo $(OBJ)执行 make 命令,得到的值是“.c ”。文件 "hacks" 没有后缀名,所以返回的是空值。
函数使用格式如下:
$(basename <names>)
函数说明:从文件名序列 names 中取出各个文件名的前缀部分。返回值为被取出来的文件的前缀名,如果文件没有前缀名则返回空的字符串。
实例:
OBJ=$(notdir src/foo.c hacks) all: @echo $(OBJ)执行 make 命令,得到值是“src/foo hacks”。获取的是文件的前缀名,包含文件路径的部分。
函数使用格式如下:
$(addsuffix <suffix>,<names>)
函数说明:把后缀 suffix 加到 names 中的每个单词后面。返回值为添加上后缀的文件名序列。
实例:
OBJ=$(addsuffix .c,src/foo.c hacks) all: @echo $(OBJ)执行 make 后得到“sec/foo.c.c hack.c”。如果文件本来就存在后缀名,依然会加上后缀。
函数使用格式如下:
$(addperfix <prefix>,<names>)
函数说明:把前缀 prefix 加到 names 中的每个单词的前面。返回值为添加上前缀的文件名序列。
实例:
OBJ=$(addprefix src/, foo.c hacks) all: @echo $(OBJ)执行 make 命令后得到 "src/foo.c src/hacks" 。我们可以使用这个函数给文件添加路径。
函数使用格式如下:
$(join <list1>,<list2>)
函数说明:把 list2 中的单词对应位置地拼接到 list1 的后面。返回值为拼接好的字符串。
实例:
OBJ=$(join src car,abc zxc qwe) all: @echo $(OBJ)执行 make 命令后得到“srcabc carzxc qwe”。很显然,
<list1>
中的文件名比<list2>
的少,所以多出来的保持不变。
函数使用格式如下:
$(wildcard PATTERN)
函数说明:列出当前目录下所有符合模式的 PATTERN 格式的文件名。返回值为当前目录下的所有符合模式 PATTERN 的文件名,它们以空格分隔。
实例:
OBJ=$(wildcard *.c *.h) all: @echo $(OBJ)执行 make 命令,可以得到当前函数下所有的 ".c " 和 ".h" 结尾的文件。这个函数通常跟的通配符 "*" 连用,一般使用在依赖规则的描述中。
函数使用格式如下:
$(foreach <var>,<list>,<text>)
函数说明:把参数
<list>
中的单词逐一取出放到参数<var>
所指定的变量中,然后再执行<text>
所包含的表达式。每一次<text>
会返回一个字符串,循环过程中,<text>
返回的每个字符串会以空格分割,最后当整个循环结束的时候,<text>
所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值。所以<var>
最好是一个变量名,<list>
可以是一个表达式,而<text>
中一般会只用<var>
这个参数来枚举<list>
中的单词。实例:
name:=a b c d files:=$(foreach n,$(names),$(n).o) all: @echo $(files)执行 make 命令,我们得到的值是“a.o b.o c.o d.o”。
注意,foreach 中的
<var>
参数是一个临时的局部变量,foreach 函数执行完后,参数<var>
的变量将不再起作用,其作用域只在 foreach 函数当中。
函数使用格式如下:
$(if <condition>,<then-part>)或(if<condition>,<then-part>,<else-part>)
函数说明:if函数的参数可以是两个,也可以是三个。
condition
参数是 if 表达式,如果其返回的是非空的字符串,那么这个表达式就相当于返回真,于是then-part
就会被计算,否则else-part
会被计算。如果condition
为真(非空字符串),那么then-part
会是整个函数的返回值;如果condition
为假(空字符串),那么else-part
将会是这个函数的返回值,此时如果else-part
没有被定义,则函数返回空字串符。then-part
和else-part
只会有一个被计算。实例:
OBJ:=foo.c OBJ:=$(if $(OBJ),$(OBJ),main.c) all: @echo $(OBJ)执行 make 命令得到 foo.c,如果变量 OBJ 的值为空,执行 make 命令得到
main.c
。
函数使用格式:
$(call <expression>,<parm1>,<parm2>,<parm3>,...)
函数说明:当 make 执行这个函数的时候,
expression
参数中的变量$(1)、$(2)、$(3)等,会被参数parm1
,parm2
,parm3
依次取代,而expression
的返回值就是 call 函数的返回值。我们可以写一个非常复杂的表达式,在这个表达式中,我们可以定义很多的参数,然后使用 call 函数来向这个表达式传递参数。实例 1:
reverse = $(1) $(2) foo = $(call reverse,a,b) all: @echo $(foo)那么,foo 的值就是“a b”。当然,参数的次序可以是自定义的,不一定是顺序的,比如:
实例 2:
reverse = $(2) $(1) foo = $(call reverse,a,b) all: @echo $(foo)此时的 foo 的值就是“b a”。
函数使用格式:
$(origin <variable>)
函数说明:origin 函数通过返回值告知使用者这个变量是哪里来的。注意,variable 是变量的名字,不应该是引用,所以不要在 variable 中使用“$”字符。
下面是origin函数返回值:
- “undefined”:如果<variable>从来没有定义过,函数将返回这个值。
- “default”:如果<variable>是一个默认的定义,比如说“CC”这个变量。
- “environment”:如果<variable>是一个环境变量并且当Makefile被执行的时候,“-e”参数没有被打开。
- “file”:如果<variable>这个变量被定义在Makefile中,将会返回这个值。
- “command line”:如果<variable>这个变量是被命令执行的,将会返回这个值。
- “override”:如果<variable>是被override指示符重新定义的。
- “automatic”:如果<variable>是一个命令运行中的自动化变量。
这些信息对于编写 Makefile 是非常有用的。假设有一个 Makefile文件,定义了一个变量
bletch
,而环境变量中也有一个环境变量bletch。我们
判断这个变量是不是环境变量,如果是则将它重定义,如果不是则不重新定义。于是,我们在 Makefile 中,可以这样写:
ifdef bletch ifeq "$(origin bletch)" "environment" bletch = barf,gag,etc endif endif当然,使用
override
关键字也可以重新定义环境中的变量,但是override
会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不是重新定义命令行传来的。