在模式规则中,目标和依赖文件都是一系列的文件,那么我们如何书写一个命令来完成从不同的依赖文件生成相应的目标?因为每次解析模式规则时,都会是不同的目标和依赖文件。
自动化变量就是完成这个功能的。所谓自动化变量就是把模式中所定义的一些列的文件自动地挨个取出,直至所有的符合模式的文件都取完。这种自动化变量只应该出现在规则的命令中,下面是所有自动化变量及其说明:
$@:
表示规则中的目标文件集。在模式规则中,如果有多个目标,那么$@就是匹配于目标中模式定义的集合。
$<:
依赖目标中的第一个目标名字
$^:
所有的依赖目标的集合。
$*:
这个变量表示目标模式中%及其之前的部分。如果目标是"dir/a.foo.b",并且目标的模式是"a.%.b",那么"$*"的值就是"dir/a.foo"。如果目标中没有模式的定义,那么$*也就不能被推导出,但是,如果目标文件的后缀是make所识别的,那么$*就是出来后缀的那部分。例如,如果目标是foo.c,因为.c是make所能识别的后缀名,所以,$*的值就是foo,这是GUN make的。所以应该尽量避免使用$*,除非是在隐含规则或者静态模式中。如果目标中的后缀是make所不能识别的,那么$*就是空
例子中,规则描述了所有的.o文件的依赖文件为对应的.c文件,对于目标“foo.o”,取其茎“foo”替代对应的依赖模式“%.c”中的模式字符“%”之后可得到目标的依赖文件“foo.c”。这就是目标“foo.o”的依赖关系“foo.o: foo.c”,规则的命令行描述了如何完成由“foo.c”编译生成目标“foo.o”。命令行中“$<”和“$@”是自动化变量,“$<”表示规则中的第一个依赖文件,“$@”表示规则中的目标文件(可参考 3.14 自动产生依赖 一节)。以上的规则就是描述了以下两个具体的规则:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
在使用静态模式规则时,指定的目标必须和目标模式相匹配,否则在执行make时将会得到一个错误提示。如果存在一个文件列表,其中一部分符合某一种模式而另外一部分符合另外一种模式,这种情况下我们可以使用“filter”函数(可参考 第七章 make的内嵌函数)来对这个文件列表进行分类,在分类之后对确定的某一类使用模式规则。例如:
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))的结果为“bar.o lose.o”。“filter”函数过滤不符合“%.o”模式的文件名而至返回所有符合此模式的文件列表。第一条静态模式规则描述了这些目标文件是通过编译对应的.c源文件来重建的。同样第二条规则也是使用这种方式。
我们通过另外一个例子来看一下自动环变量“$*”在静态模式规则中的使用方法:
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
当执行此规则的命令时,自动环变量“$*”被展开为“茎”。在这里就是“big”和“little”。
静态模式规则在一个较大的工程中非常有用的。它可以对一个工程中的同类文件的重建规则进行一次定义,而实现对整个工程中此类文件指定相同的重建规则。比如,可以用来描述整个工程中所有的.o文件的依赖规则和编译命令。通常的做法是将生成同一类目标的模式定义在一个make.rules的文件中。在工程各个模块的Makefile中包含此文件。
原文地址:http://blog.csdn.net/getnextwindow/article/details/25591825