Makefile 自动化变量

10.5.3 自动化变量


模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。
假如你需要书写一个将.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”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。


$(<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”来禁止这一
特性。
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值