模式规则函数
模式规则相似于普通规则。只是在模式规则中,目标名中须要包含有模式字符“%”(一个),包含有模式字符“%”的目标被用来匹配一个文件名,“%”能够匹配任何非空字符串。规则的依赖文件中一样可使用“%”,依赖文件中模式字符“%”的取值状况由目标中的“%”来决定。例如:对于模式规则“%.o : %.c”,它表示的含义是:全部的.o文件依赖于对应的.c文件。咱们可使用模式规则来定义隐含规则。命令行
要注意的是:模式字符“%”的匹配和替换发生在规则中全部变量和函数引用展开以后,变量和函数的展开通常发生在make读取Makefile时(变量和函数的展开可参考第五 章 使用变量 和 第七章 make的函数),而模式规则中的“%”的匹配和替换则发生在make执行时。debug
模式规则介绍字符串
在模式规则中,目标文件是一个带有模式字符“%”的文件,使用模式来匹配目标文件。文件名中的模式字符“%”能够匹配任何非空字符串,除模式字符之外的部分要求一致。例如:“%.c”匹配全部以“.c”结尾的文件(匹配的文件名长度最少为3个字母),“s%.c”匹配全部第一个字母为“s”,并且必须以“.c”结尾的文件,文件名长度最小为5个字符(模式字符“%”至少匹配一个字符)。在目标文件名中“%”匹配的部分称为“茎”(前面已经提到过,参考4.12 静态模式一节)。使用模式规则时,目标文件匹配以后获得“茎”,依赖根据“茎”产生对应的依赖文件,这个依赖文件必须是存在的或者可被建立的。自动化
所以,一个模式规则的格式为:编译
%.o : %.c ; COMMAND... class
这个模式规则指定了如何由文件“N.c”来建立文件“N.o”,文件“N.c”应该是已存在的或者可被建立的。变量
模式规则中依赖文件也能够不包含模式字符“%”。当依赖文件名中不包含模式字符“%”时,其含义是全部符合目标模式的目标文件都依赖于一个指定的文件(例如:%.o : debug.h,表示全部的.o文件都依赖于头文件“debug.h”)。这样的模式规则在不少场合是很是有用的。file
同 样一个模式规则能够存在多个目标。多目标的模式规则和普通多目标规则有些不一样,普通多目标规则的处理是将每个目标做为一个独立的规则来处理,因此多个目 标就就对应多个独立的规则(这些规则各自有本身的命令行,各个规则的命令行可能相同)。但对于多目标模式规则来讲,全部规则的目标共同拥有依赖文件和规则 的命令行,当文件符合多个目标模式中的任何一个时,规则定义的命令就有可能将会执行;由于多个目标共同拥有规则的命令行,所以一次命令执行以后,规则不会 再去检查是否须要重建符合其它模式的目标。看一个例子:引用
#sample Makefile
Objects = foo.o bar.o
CFLAGS := -Wall
%x : CFLAGS += -g
%.o : CFLAGS += -O2
%.o %.x : %.c
$(CC) $(CFLAGS) $< -o $@
当在命令行中执行“make foo.o foo.x”时,会看到只有一个文件“foo.o”被建立了,同时make会提示“foo.x”文件是最新的(其实“foo.x”并无被建立)。此过程代表了多目标的模式规则在make处理时是被做为一个总体来处理的。这是多目标模式规则和多目标的普通规则的区别之处。你们不妨将上边的例子改成普通多目标规则试试看将会获得什么样的结果。
最后须要说明的是:
1. 模式规则在Makefile中的顺序须要注意,当一个目标文件同时符合多个目标模式时,make将会把第一个目标匹配的模式规则做为重建它的规则。
2. Makefile中明确指定的模式规则会覆盖隐含模式规则。就是说若是在Makefile中出现了一个对目标文件合适可用的模式规则,那么make就不会再为这个目标文件寻找其它隐含规则,而直接使用在Makefile中出现的这个规则。在使用时,明确规则永远优先于隐含规则。
3. 另外,依赖文件存在或者被说起的规则,优先于那些须要使用隐含规则来建立其依赖文件的规则。
模式规则示例
本小节来看一些使用模式规则的例子,这些模式规则在GNU make中已经被预约义。首先看编译.c文件到.o文件的隐含模式规则:
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
此规则描述了一个.o文件如何由对应的.c文件建立。规则的命令行中使用了自动化变量“$<”和“$@”,其中自动化变量“$<”表明规则的依赖,“$@”表明规则的目标。此规则在执行时,命令行中的自动化变量将根据实际的目标和依赖文件取对应值。关于自动化变量可参考10.5.3 自动化变量一节
make中第二个内嵌模式规则是:
% :: RCS/%,v
$(CO) $(COFLAGS) $<
这个规则的含义是:任何一个文件“X”均可以由目录“RCS”下的相应文件“x.v”来生成。规则的目标为“%”,它匹配任何文件名,所以只要存在相对应的依赖文件(N.v),目标(N)均可被建立。双冒号表示该规则是最终规则,意味着规则的依赖文件不是中间过程文件。参考10.6 万用规则一节
另外,一个具备多目标的隐含规则是:
%.tab.c %.tab.h: %.y
bison -d $<
它是一个多目标模式规则,关于多目标的特征可参考 10.5.1 模式规则介绍一小节最后一个例子。