Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177332
  • 博文数量: 37
  • 博客积分: 1110
  • 博客等级: 少尉
  • 技术积分: 395
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-29 22:01
文章分类

全部博文(37)

文章存档

2013年(10)

2011年(2)

2010年(25)

我的朋友

分类: 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中的eeEE,结果是新的字符串fEEt on the strEEt

 

2$(patsubst PATTERN,REPLACEMENT,TEXT)

 

函数名称:模式替换函数patsubst

函数功能:搜索TEXT中以空格分开的单词,将否符合模式PATTERN替换为REPLACEMENT。参数PATTERN中可以使用模式通配符%来代表一个单词中的若干字符。如果参数REPLACEMENT中也包含一个%,那么REPLACEMENT中的%将是PATTERN中的那个%所代表的字符串。在PATTERNREPLACEMENT中,只有第一个%被作为模式字符来处理,后续的作为字符本上来处理。在两个参数中当使用第一个%本是字符本身时,可使用反斜杠\对它进行转义处理(转义处理的机制和使用静态模式的转义一致。

返回值:替换后的新字符串。

函数说明:参数TEXT单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。

示例:

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

 

把字串x.c.c bar.c中以.c 结尾的单词替换成以.o 结尾的字符。函数的返回结果是x.c.o bar.o

本文的第五章在 变量的高级用法的第一小节 中我们曾经讨论了变量的替换引用,它是一个简化版的patsubst函数在变量引用过程的实现。变量替换引用中:


     $(VAR:PATTERN=REPLACEMENT)

 

就等于:

$(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))

实现了去除变量objectsmains定义的字串(文件名)功能。它的返回值为foo.o bar.o


 

 7$(sort LIST)

 

函数名称:排序函数sort

函数功能:给字串LIST中的单词以首字母为准进行排序(升序),并取掉重复的单词。

返回值:空格分割的没有重复单词的字串。

函数说明:两个功能,排序和去字串中的重复单词。可以单独使用其中一个功能。

示例:

$(sort foo bar lose foo)

 

返回值为:bar foo lose

 

8$(word N,TEXT)

 

函数名称:取单词函数word

函数功能:取字串TEXT中第N个单词(N的值从 1 开始)。

返回值:返回字串TEXT中第N个单词。

函数说明:如果N值大于字串TEXT中单词的数目,返回空字符串。如果N0出错!

示例:

$(word 2, foo bar baz)

返回值为bar

 

9$(wordlist S,E,TEXT)

 

函数名称:取字串函数wordlist

函数功能:从字串TEXT中取出从S开始到E的单词串。SE表示单词在字串中位置的数字。

返回值:字串TEXT中从第SE(包括E)的单词字串。

函数说明:SE都是从 1 开始的数字。STEXT中的字数大时,返回空。如果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时可搭配使用,来实现复杂功能。最后我们使用这些函数来实现一个实际应用的需求。例子中我们使用函数substpatsbustMakefile中可以使用变量VPATH来指定搜索路径。我们的例子中需要指定所有头文件的搜索路径也在这些目录下。头文件的搜索路径需要使用GCC-I参数通过命令行选项来实现,而通过VPATH罗列的目录是用冒号:分割的。如下就是Makefile的片段:

……

VPATH = src:../includes

override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))

…….

那么第二条语句所实现的功能就是CFLAGS += -Isrc –I../includes

阅读(796) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-11-08 15:26:29

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com