makefile详解(五)

本文详细介绍了Makefile中的各种内置函数,包括文本处理函数、文件名称处理函数、条件和流程控制函数、变量操作函数以及系统函数。并通过实例展示了如何在Makefile中使用这些函数。

PS:直接从WORD拷贝,未对格式进行仔细整理

7 函数

在makefile中,还可以使用函数。函数分为两类:一种是makefile自带的函数,称之为内置函数;一种是用户自定义函数,也就是说我们可以自己在makefile中编写函数。

 

内置函数又大致可分为:文本处理函数,文件名称处理函数,条件和流程控制函数,变量操作函数,系统函数。

在makefile中调用函数的语法如下:

$(函数名称 函数参数 [, 函数参数[,...]])

 

在本章节剩下的内容中,将按函数的分类罗列出makefile中主要的内置函数。由于内置函数较多,只会对其中小部分给出例子,其他都只说明函数的用途。

 

关于用户自定义函数,这里就不介绍了,读者如果感兴趣,可以自行查找资料。

 

7.1 文本处理函数

文件处理函数是用来处理make变量的,在makefile中变量的值都是字符串类型的(即文本类型)

1.  $(subst find_text, replacement_text, original_text)

作用:把文本original_text中出现的每个find_text替换为replacement_text后再展开。

 

例1     使用subst函数

env.txt文件:

project/src;project/include;project/obj        

 

build.bat批处理文件:

……

set /P PRO_FILE_PATH = <env.txt

make –f substExample.mk

……

 

substExample.mk文件:

……

VPATH = $(subst ;,:,$( PRO_FILE_PATH))       

……

 

在例20中,我们将项目文件的所在的路径保存在了env.txt中,每个路径用分号分割;我们希望在VPATH内置变量中使用这些路径,但是VPATH中路径又是用冒号分割的,因此使用subst函数将分号替换成冒号。2. $(patsubst PATTERN,REPLACEMENT,TEXT)

2.  $(patsubst find_pattern, replacement_pattern, original_text)

作用:将文本original_text中满足find_pattern模式的内容替换成replacement_pattern模式的文本。

例2     使用patsubst函数

SRCFILES := circle.c square.c triangle.c rectangle.c

 

shapes:$(patsubst %.c,%.o,$(SRCFILES))

$(CC) $(LDFLGAS) –o $@  $^

 

%.o : %.c

         $(CC) $(CFLAGS) –o $@ –c $<

例21的makefile与下面makefile是等同的:

shapes:circle.o square.o triangle.o rectangle.o

$(CC) $(LDFLGAS) –o $@  $^

 

%.o : %.c

         $(CC) $(CFLAGS) –o $@ –c $<

 

3.  $(strip original_text)

作用:删除文本original_text前面和后面的空白(white space),并将中间每个“没有引号围起来”的空格序列替换为一个空格字符

4.  $(findstring find_text, original_text)

作用:如果在original_text内找到匹配的字符串,就展开为find_text的值;如果没有找到,就展开为空值。

例如:

$(findstring a,a b c)

$(findstring a,b c)

就分别展开为“a”和“”(空字符串)。

5.  $(filter find_patterns, original_text)

作用:original_text中删除所有与任一个find_patterns都不匹配的词,只返回匹配的词。

例3     使用filter函数

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

foo: $(sources)

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

展开后与下面的makfile等同:

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

 gcc foo.c bar.c baz.s –o foo

6.  $(filter-out find_patterns, original_text)

作用:original_text中删除所有与find_patterns匹配的词,只返回不匹配的词。它与函数filter正好相反。

7.  $(sort original_text)

作用:按字母顺序排列original_text内的词(word),并删除重复元素后展开。

8.  $(word n, original_text)

作用:展开为original_text内的第n个词(word)

9.  $(firstword  original_text)

作用:与$(word 1, original_text)等同

10. $(wordlist  n,m,original_text)

作用:展开为original_text内的第n个词(word)到第m个词

11. $( words original_text)

作用:展开为original_text内的词(word)的数量

 

7.2 文件名称处理函数

1.  $(dir filename_list)

作用:展开为变量filename中每个文件名的目录部分列表

例如:$(dir src/foo.c hacks)展开后为“src/ ./”。

2.  $(notdir filename_list)

作用:展开为变量filename文件名列表,删除目录部分

例如:$(notdir src/foo.c hacks) 展开后为“foo.c hacks”。

3.  $(suffix filename_list)

作用:展开为扩展名

例如:$(suffix src/foo.c hacks) 展开后为“.c”。

4.  $(basename filename_list)

作用:展开为文件名列表,删除它们的扩展名,目录部分不变动。

例如:$(basename src/foo.c hacks) 展开后为“src/foo hacks”。

5.  $(addsuffix suffix,filename_list)

作用:展开为文件名,并在后面加上后缀suffix。

例如:$(addsuffix .c, foo bar) 展开后为“foo.c bar.c”。

6.  $(addprefix prefix,filename_list)

作用:展开为文件名,并加上前缀prefix。

例如:$(addprefix src/, foo bar)展开后为“src/foo src/bar”。

7.  $(join prefix_list,suffix_list)

作用:把两个参数一个词一个词地结合起来。如果某个参数的词的个数比另一个多,多出来的词不加变化地复制到结果中。

例如:“$(join a b,.c .o)” 展开后为“a.c b.o”。

8.  $(wildcard glob)

作用:展开为“符合glob模式”的既有文件名,这个模式通常包含shell通配符。

 

7.3 条件和流程处理函数

这里列出的函数,可以进行有条件的操作,迭代地处理列表,或者执行一个变量的内容。

1.  $(foreach var, list, expression)

作用:遍历list中的每个词并赋给临时变量var,在将var的结果根据表达式expression扩展;将每次遍历扩展的结果通过空格进行连接,生成foreach的最终结果。

例4     使用foreach函数(1)

dirs := project/src project/include

files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

 

假设在project/src目录下有如下文件:circle.c square.c, project/include目录下有如下文件:circle.h, square.h,则变量files最终的值为“project/src/circle.c project/src/square.c project/include/ circle.h project/include/square.h” files变量的值为两个目录下所有文件的完整文件名列表。

 

如果我们只想列出两个目录下所有文件的文件名,则可以这么做:

例5     使用foreach函数(2)

dirs := project/src project/include

files := $(foreach dir,$(dirs),$(notdir, $(wildcard $(dir)/*) ))

files的值将是“circle.c square.c circle.h, square.h

 

2.  $(if conditon, then_text[, else_text])

作用:如果删除文本conditon前面和后面的空格后,展开为非空,则展开为then_text,否则展开为else_text

 

3.  $(eval text)

作用:把text展开视为被包含的makefile文字。

 

7.4 变量操作函数


1.  $(value variable_name)

作用:展开为变量名称的“原始”值,没有进一步展开它可能包含的任何变量引用。

2.  $(origin variable_name)

作用:展开为如下值中的一个,来指示变量是如何被定义的:

undefined

variable未被定义。

default

variable有一个缺省定义。注意,如果重新定义了一个缺省变量,返回的就是后一个定义的原因。

environment

variable被定义为环境变量,而且没有打开“-e”选项。

 environment override

variable被定义为环境变量,“-e”选项被打开。

file

variable在一个构造文件中被定义。

command line

variable在命令行中被定义。

override

variable在一个构造文件中用override指令定义。

automatic

variable是为每条规则所执行的命令定义的自动变量。

 

3.  $(call variable_name, argument[,argument[,…]])

作用:展开变量,把表达式中有编号的变量($1,$2…)替换为保留的变量。实际上,使用此内置函数可以创建自定义类函数宏。

7.5 系统函数

系统函数,可以实现与make环境的交互。

1.      $(shell text)

作用:将”text”展开传递给shell。此函数会展开为最终shell命令的标准输出。

2.      $(error text)

作用:make把text文字的展开当作错误信息而输出,然后退出。

3.      $(warning text)

作用:类似于error命令,不同的是make不会退出。此函数展开为”空”

七、静态模式 静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活。我们还是先来看一下语法: ;: ;: ; ; ... targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。 target-parrtern是指明了targets的模式,也就是的目标集模式。 prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。 这样描述这三个东西,可能还是没有说清楚,还是举个例子来说明一下吧。如果我们的;定义成“%.o”,意 思是我们的;集合中都是以“.o”结尾的,而如果我们的;定义成“%. c”,意思是对;所形成的目标集进行二次定义,其计算方法是,取;模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。 所以,我们的“目标模式”或是“依赖模式”中都应该有“%”这个字符,如果你的文件名中有“%”那么你可以使用反斜杠“\”进行转义,来标明真实的“%”字符。 看一个例子: objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ 上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)。于是,上面的规则展开后等价于下面的规则: foo.o : foo.c $(CC) -c $(CFLAGS) foo.c -o foo.o bar.o : bar.c $(CC) -c $(CFLAGS) bar.c -o bar.o 试想,如果我们的“%.o”有几百个,那种我们只要用这种很简单的“静态模式规则”就可以写完一堆规则,实在是太有效率了。“静态模式规则”的用法很灵活,如果用得好,那会一个很强大的功能。再看一个例子: files = foo.elc bar.o lose.o $(filter %.o,$(files)): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ $(filter %.elc,$(files)): %.elc: %.el emacs -f batch-byte-compile $< $(filter %.o,$(files))表示调用Makefile的filter函数,过滤“$filter”集,只要其中模式为“%.o”的内容。其的它内容,我就不用多说了吧。这个例字展示了Makefile中更大的弹性。 八、自动生成依赖性 在Makefile中,我们的依赖关系可能会需要包含一系列的头文件,比如,如果我们的main.c中有一句“#include "defs.h"”,那么我们的依赖关系应该是: main.o : main.c defs.h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值