分类: LINUX
2010-11-07 21:30:46
一、函数的调用语法
GNU make 函数的调用格式类似于变量的引用格式,以“$”开头表示一个引用的过程。语法格式如下:
$(FUNCTION ARGUMENTS)
或者:
${FUNCTION ARGUMENTS}
对于函数调用的格式有以下几点说明:
1. 语法格式中“FUNCTION”是需要调用的函数名,它是 make 内嵌的函数名。对于用户自己的函数需要通过 make 的“call”函数来间接调用。
2. “ARGUMENTS”是函数的参数,参数和函数名之间使用若干个空格或者[tab]字符分割(建议使用一个空格,这样不仅使在书写上比较直观,更重要的是当你不能确定哪些地方是允许用[Tab]时候,避免不必要的麻烦);如果存在多个参数时,参数之间使用逗号“,”分割。
3. 以“$”开头,使用成对的圆括号或花括号把函数名和参数括起(在 Makefile 中,圆括号和花括号在任何地方必须成对出现)。参数中存在变量或者函数的引用时,对它们使用所使用的分界符(圆括号或者花括号)建议使用和引用函数使用的相同。最好不要使用两种不同的括号。建议在变量的引用和函数的引用中统一使用圆括号;这样在使用“vim”编辑器书写 Makefile 时,使用圆括它可以亮度显式 make 的内嵌函数名,避免函数名的拼写错误。一般在 Makefile 中应该这样来书写“$(sort $(x))”;而不是“$(sort ${x})”和其它几种。
4. 函数处理参数时,参数中如果存在对其它变量或者函数的引用,首先对这些引用进行展开得到参数的实际内容。而后才对它们进行处理。参数的展开顺序是按照参数的先后顺序来进行的。
5. 书写时,函数的参数中不能出现逗号“,”和空格。这是因为逗号被作为多个参数的分隔符,前导空格会被忽略。在实际书写 Makefile 时,当需要使用这两个作为函数的参数时,可以把它们赋值给变量,在函数的参数中使用相应的变量引用。我们来看一个这样的例子:
comma:= ,
empty:=
space:= $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
这样我们就实现了“bar”的值是“a,b,c”。
二、文本处理函数
以下是 GNU make 内嵌的文本(字符串)处理函数。
1、$(subst FROM,TO,TEXT)
函数名称:字符串替换函数—subst。
函数功能:把字串“TEXT”中的“FROM”字符替换为“TO”。
返回值:替换后的新字符串。
示例:
$(subst ee,EE,feet on the street)
替换“feet on the street”中的“ee”为“EE”,结果是新的字符串“fEEt on the strEEt”。
2、$(patsubst PATTERN,REPLACEMENT,TEXT)
函数名称:模式替换函数—patsubst。
函数功能:搜索“TEXT”中以空格分开的单词,将否符合模式“PATTERN”替换为“REPLACEMENT”。参数“PATTERN”中可以使用模式通配符“%”来代表一个单词中的若干字符。如果参数“REPLACEMENT”中也包含一个“ %”,那么“REPLACEMENT”中的“%”将是“PATTERN”中的那个“%”所代表的字符串。在“PATTERN”和“REPLACEMENT”中,只有第一个“%”被作为模式字符来处理,后续的作为字符本上来处理。在两个参数中当使用第一个“%”本是字符本身时,可使用反斜杠“\”对它进行转义处理(转义处理的机制和使用静态模式的转义一致。
返回值:替换后的新字符串。
函数说明:参数“TEXT”单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.c bar.c”中以.c 结尾的单词替换成以.o 结尾的字符。函数的返回结果是“x.c.o bar.o”
本文的第五章在 变量的高级用法的第一小节 中我们曾经讨论了变量的替换引用,它是一个简化版的“patsubst”函数在变量引用过程的实现。变量替换引用中:
就等于:
$(patsubst PATTERN,REPLACEMENT,$(VAR))
而另外一种更为简单的替换字符后缀的实现:
$(VAR:SUFFIX=REPLACEMENT)
它等于:
$(patsubst %SUFFIX,%REPLACEMENT,$(VAR))
例如我们存在一个代表所有.o 文件的变量。定义为“objects = foo.o bar.o baz.o”。为了得到这些.o 文件所对应的.c 源文件。我们可以使用以下两种方式的任意一个:
$(objects:.o=.c)
$(patsubst %.o,%.c,$(objects))
3、$(strip STRINT)
函数名称:去空格函数—strip。
函数功能:去掉字串(若干单词,使用若干空字符分割)“STRINT”开头和结尾的空字符,并将其中多个连续空字符合并为一个空字符。
返回值:无前导和结尾空字符、使用单一空格分割的多单词字符串。
函数说明:空字符包括空格、[Tab]等不可显示字符。
示例:
STR = a b c
LOSTR = $(strip $(STR))
结果是“a b c”。
“strip”函数经常用在条件判断语句的表达式中,确保表达式比较的可靠和健壮!
4、$(findstring FIND,IN)
函数名称:查找字符串函数—findstring。
函数功能:搜索字串“IN”,查找“FIND”字串。
返回值:如果在“IN”之中存在“FIND”,则返回“FIND”,否则返回空。
函数说明:字串“IN”之中可以包含空格、[Tab]。搜索需要是严格的文本匹配。
示例:
$(findstring a,a b c)
$(findstring a,b c)
第一个函数结果是字“a”;第二个值为空字符。
5、$(filter PATTERN…,TEXT)
函数名称:过滤函数—filter。
函数功能:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字符“%”。存在多个模式时,模式表达式之间使用空格分割。
返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。
函数说明:“filter”函数可以用来去除一个变量中的某些字符串,我们下边的例子中就是用到了此函数。
示例:
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
使用“$(filter %.c %.s,$(sources))”的返回值给 cc 来编译生成目标“foo”,函数返回值为“foo.c bar.c baz.s”。
6、$(filter-out PATTERN...,TEXT)
函数名称:反过滤函数—filter-out。
函数功能:和“filter”函数事项的功能相反。过滤掉字串“TEXT”中所有符合模式“PATTERN”的单词,保留所有不符合此模式的单词。可以有多个模式。存在多个模式时,模式表达式之间使用空格分割。
返回值:空格分割的“TEXT”字串中所有不符合模式“PATTERN”的字串。
函数说明:“filter-out”函数也可以用来去除一个变量中的某些字符串,(实现和“filter”函数相反)。
示例:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
$(filter-out $(mains),$(objects))
实现了去除变量“objects”中“mains”定义的字串(文件名)功能。它的返回值为“foo.o bar.o”。
函数名称:排序函数—sort。
函数功能:给字串“LIST”中的单词以首字母为准进行排序(升序),并取掉重复的单词。
返回值:空格分割的没有重复单词的字串。
函数说明:两个功能,排序和去字串中的重复单词。可以单独使用其中一个功能。
示例:
$(sort foo bar lose foo)
返回值为:“bar foo lose”。
8、$(word N,TEXT)
函数名称:取单词函数—word。
函数功能:取字串“TEXT”中第“N”个单词(“N”的值从 1 开始)。
返回值:返回字串“TEXT”中第“N”个单词。
函数说明:如果“N”值大于字串“TEXT”中单词的数目,返回空字符串。如果“N”为 0,出错!
示例:
$(word 2, foo bar baz)
返回值为“bar”。
9、$(wordlist S,E,TEXT)
函数名称:取字串函数—wordlist。
函数功能:从字串“TEXT”中取出从“S”开始到“E”的单词串。“S”和“E”表示单词在字串中位置的数字。
返回值:字串“TEXT”中从第“S”到“E”(包括“E”)的单词字串。
函数说明:“S”和“E”都是从 1 开始的数字。当“S”比“TEXT”中的字数大时,返回空。如果“E”大于“TEXT”字数,返回从“S”开始,到“TEXT”结束的单词串。如果“S”大于“E”,返回空。
示例:
$(wordlist 2, 3, foo bar baz)
返回值为:“bar baz”。
10、$(words TEXT)
函数名称:统计单词数目函数—words。
函数功能:字算字串“TEXT”中单词的数目。
返回值:“TEXT”字串中的单词数。
示例:
$(words, foo bar)
返回值是“2”。所以字串“TEXT”的最后一个单词就是:$(word $(words TEXT),TEXT)。
11、$(firstword NAMES…)
函数名称:取首单词函数—firstword。
函数功能:取字串“NAMES…”中的第一个单词。
返回值:字串“NAMES…”的第一个单词。
函数说明:“NAMES”被认为是使用空格分割的多个单词(名字)的序列。函数忽略“NAMES…”中除第一个单词以外的所有的单词。
示例:
$(firstword foo bar)
返回值为“foo”。函数“firstword”实现的功能等效于“$(word 1, NAMES…)”。
以上 11个函数是make内嵌的的文本处理函数。在书写Makefile时可搭配使用,来实现复杂功能。最后我们使用这些函数来实现一个实际应用的需求。例子中我们使用函数“subst”和“patsbust”。Makefile中可以使用变量“VPATH”来指定搜索路径。我们的例子中需要指定所有头文件的搜索路径也在这些目录下。头文件的搜索路径需要使用GCC的“-I”参数通过命令行选项来实现,而通过“VPATH”罗列的目录是用冒号“:”分割的。如下就是Makefile的片段:
……
VPATH = src:../includes
override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
…….
那么第二条语句所实现的功能就是“CFLAGS += -Isrc –I../includes”。
chinaunix网友2010-11-08 15:26:29
很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com