10.5.3 Automatic Variables

https://www.gnu.org/software/make/manual/make.html#Automatic-Variables

10.5.3 Automatic Variables


Suppose you are writing a pattern rule to compile a ‘.c’ file into a ‘.o’ file: how do you write the ‘cc’ command so that it operates on the right source file name? You cannot write the name in the recipe, because the name is different each time the implicit rule is applied.
What you do is use a special feature of make, the automatic variables. These variables have values computed afresh for each rule that is executed, based on the target and prerequisites of the rule. In this example, you would use ‘$@’ for the object file name and ‘$<’ for the source file name.

It’s very important that you recognize the limited scope in which automatic variable values are available: they only have values within the recipe. In particular, you cannot use them anywhere within the target list of a rule; they have no value there and will expand to the empty string. Also, they cannot be accessed directly within the prerequisite list of a rule. A common mistake is attempting to use $@ within the prerequisites list; this will not work. However, there is a special feature of GNU make, secondary expansion (see Secondary Expansion), which will allow automatic variable values to be used in prerequisite lists.
Here is a table of automatic variables:
$@
The file name of the target of the rule. If the target is an archive member, then ‘$@’ is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ‘$@’ is the name of whichever target caused the rule’s recipe to be run.
$%
The target member name, when the target is an archive member. See Archives. For example, if the target is foo.a(bar.o) then ‘$%’ is bar.o and ‘$@’ is foo.a. ‘$%’ is empty when the target is not an archive member.
$<
The name of the first prerequisite. If the target got its recipe from an implicit rule, this will be the first prerequisite added by the implicit rule (see Implicit Rules).
$?
The names of all the prerequisites that are newer than the target, with spaces between them. For prerequisites which are archive members, only the named member is used (see Archives).
$^
The names of all the prerequisites, with spaces between them. For prerequisites which are archive members, only the named member is used (see Archives). A target has only one prerequisite on each other file it depends on, no matter how many times each file is listed as a prerequisite. So if you list a prerequisite more than once for a target, the value of $^ contains just one copy of the name. This list does not contain any of the order-only prerequisites; for those see the ‘$|’ variable, below.
$+
This is like ‘$^’, but prerequisites listed more than once are duplicated in the order they were listed in the makefile. This is primarily useful for use in linking commands where it is meaningful to repeat library file names in a particular order.
$|
The names of all the order-only prerequisites, with spaces between them.
$*
The stem with which an implicit rule matches (see How Patterns Match). If the target is dir/a.foo.b and the target pattern is a.%.b then the stem is dir/foo. The stem is useful for constructing names of related files.
In a static pattern rule, the stem is part of the file name that matched the ‘%’ in the target pattern.
In an explicit rule, there is no stem; so ‘$*’ cannot be determined in that way. Instead, if the target name ends with a recognized suffix (see Old-Fashioned Suffix Rules), ‘$*’ is set to the target name minus the suffix. For example, if the target name is ‘foo.c’, then ‘$*’ is set to ‘foo’, since ‘.c’ is a suffix. GNU make does this bizarre thing only for compatibility with other implementations of make. You should generally avoid using ‘$*’ except in implicit rules or static pattern rules.
If the target name in an explicit rule does not end with a recognized suffix, ‘$*’ is set to the empty string for that rule.
$?’ is useful even in explicit rules when you wish to operate on only the prerequisites that have changed. For example, suppose that an archive named lib is supposed to contain copies of several object files. This rule copies just the changed object files into the archive:
lib: foo.o bar.o lose.o win.o
        ar r lib $?
Of the variables listed above, four have values that are single file names, and three have values that are lists of file names. These seven have variants that get just the file’s directory name or just the file name within the directory. The variant variables’ names are formed by appending ‘D’ or ‘F’, respectively. These variants are semi-obsolete in GNU make since the functions dir and notdir can be used to get a similar effect (see Functions for File Names). Note, however, that the ‘D’ variants all omit the trailing slash which always appears in the output of the dir function. Here is a table of the variants:
$(@D)
The directory part of the file name of the target, with the trailing slash removed. If the value of ‘$@’ is dir/foo.o then ‘$(@D)’ is dir. This value is . if ‘$@’ does not contain a slash.
$(@F)
The file-within-directory part of the file name of the target. If the value of ‘$@’ is dir/foo.o then ‘$(@F)’ is foo.o. ‘$(@F)’ is equivalent to ‘$(notdir $@)’.
$(*D)
$(*F)
The directory part and the file-within-directory part of the stem; dir and foo in this example.
$(%D)
$(%F)
The directory part and the file-within-directory part of the target archive member name. This makes sense only for archive member targets of the form archive(member) and is useful only when member may contain a directory name. (See Archive Members as Targets.)
$(<D)
$(<F)
The directory part and the file-within-directory part of the first prerequisite.
$(^D)
$(^F)
Lists of the directory parts and the file-within-directory parts of all prerequisites.
$(+D)
$(+F)
Lists of the directory parts and the file-within-directory parts of all prerequisites, including multiple instances of duplicated prerequisites.
$(?D)
$(?F)
Lists of the directory parts and the file-within-directory parts of all prerequisites that are newer than the target.
Note that we use a special stylistic convention when we talk about these automatic variables; we write “the value of ‘$<’”, rather than “the variable <” as we would write for ordinary variables such as objects and CFLAGS. We think this convention looks more natural in this special case. Please do not assume it has a deep significance; ‘$<’ refers to the variable named < just as ‘$(CFLAGS)’ refers to the variable named CFLAGS. You could just as well use ‘$(<)’ in place of ‘$<’.





http://www.cnblogs.com/wiessharling/p/4120943.html


$@ 
表示规则的目标文件名。如果目标是一个文档文件(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”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。 
$(<D) 
$(<F) 
分别表示规则中第一个依赖文件的目录部分和文件名部分。 
$(^D) 
$(^F) 
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 
$(+D) 
$(+F) 
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。 
$(?D) 
$(?F) 
分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了
“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我
们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
因为自动化变量本身是一个特殊字符。 
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN 
make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。 
自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一
特性

留言

這個網誌中的熱門文章

利用ffmpeg取出ts流中特定的program