makefile中的自动化变量$@,$%,$自动化变量模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时源文件名都是不一样的。为了解决这个问题,就需要使用自动环变量,自动化变量的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。下面对所有的自动化变量进行说明: $@表示规则的目标文件名。如果目标是一个文档文件(linux中,一般称.a 文件为文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式规则中,它代表的是哪个触发规则被执行的目标文件名。$%当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则的目标是foo.a(bar.o),那么, $%的值就为bar.o, $@ 的值为foo.a。如果目标不是静态库文件,其值为空。$<规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表由隐含规则加入的第一个依赖文件。$?所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员(.o 文件)。 $^规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量$^只记录它的一次引用情况。就是说变量$^会去掉重复的依赖文件。$+类似$^,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。$*在模式规则和静态模式规则中,代表茎。茎是目标模式中% 所代表的部分(当文件名中存在目录时,茎也包含目录(斜杠之前)部分,可参考 10.5.4模式的匹配 一小节)。例如:文件dir/a.foo.b,当目标的模式为a.%.b 时,$* 的值为dir/a.foo 。茎对于构造相关文件名非常有用。自动化变量$* 需要两点说明:? 对于一个明确指定的规则来说不存在茎,这种情况下$* 的含义发生改变。此时,如果目标文件名带有一个可识别的后缀(参考 10.7 后缀规则 一节),那么$* 表示文件中除后缀以外的部分。例如:foo.c则$* 的值为:foo ,因为.c 是一个可识别的文件后缀名。GUN make对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避免使用这个变量。? 当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量为空。自动化变量$?在显式规则中也是非常有用的,使用它规则可以指定只对更新以后的依赖文件进行操作。例如,静态库文件libN.a ,它由一些.o 文件组成。这个规则实现了只将更新后的.o 文件加入到库中: lib: foo.o bar.o lose.o win.o ar r lib $?以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入D或者F字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make中,在当前版本的make中,可以使用dir或者notdir函数来实现同样的功能(可参考 8.3 文件名处理函数 一节)。$(@D)表示目标文件的目录部分(不包括斜杠)。如果$@ 是dir/foo.o ,那么$(@D) 的值为dir。如果$@ 不存在斜杠,其值就是. (当前目录)。注意它和 函数dir的区别!$(@F)目标文件的完整文件名中除目录以外的部分(实际文件名)。如果$@ 为dir/foo.o ,那么$(@F) 只就是foo.o。$(@F) 等价于函数$(notdir$@) 。$(*D)$(*F)分别代表目标茎中的目录部分和文件名部分。$(%D)$(%F)当以如archive(member) 形式静态库为目标时,分别表示库文件成员member名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。$(