一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2170|回复: 0
收起左侧

makefile中的自动化变量 $@,$%,$

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$ 1 L2 m  J2 l0 \3 p  `
9 z) s- u7 f0 z2 _2 x2 Q, A& I# |# A
自动化变量 + w+ m, O! x4 C* ~. \
模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
$ w: q/ t9 f( L0 P2 x一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去7 M  f" e. V; m. T
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 6 X7 T: k4 g/ W- f" k8 B  w1 p
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写
2 {2 n0 Q( l% K5 v正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
# G4 a: }4 T1 M5 B源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量# k) v0 ^) y* y* z
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 : G7 ]/ ?1 Q- Q
下面对所有的自动化变量进行说明: . i! h7 A% @* Q0 ~" Y" N$ C
$@ + k' I! N* ]( I6 O- \
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
* Z0 J8 \. K. d6 n8 h7 g# L文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式
3 b- Y* ^; A/ }2 O规则中,它代表的是哪个触发规则被执行的目标文件名。 # C5 z* R3 D' n* C% C  I- N
$% 0 ^6 v0 n! B" K4 N( M8 P
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则2 D+ x! N0 c; @" R) t' X% U9 e
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。# v: o- Z2 `  f
如果目标不是静态库文件,其值为空。
/ D. A) s; `& w+ R) M3 w6 }  Y$< ( ^7 U9 ?) E. q! L$ r
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表4 I  R0 A7 O$ d; O0 n. P
由隐含规则加入的第一个依赖文件。 % y9 ~2 p$ V# F
$?
7 e  o/ J6 c, k& \
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。
  A$ v1 N# |# F* O, j0 D$^
- g% y0 T2 |2 _, @0 W0 I规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的% I/ {4 @/ E7 d. D) S' ~
只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量
7 `) k6 Y& g- t“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
& P& G$ `* }. J$+
# z4 i0 V, k$ i" r+ n类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库) N1 H, a0 B  S( p' y- o
的交叉引用场合。   b) K% M7 r$ J$ Z% w  O& t$ |& u& h
$*
9 Q, ~& [% B0 t$ C- k. ~3 x* {在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的
/ g% m) w1 C9 T" ]9 i4 h% S! T% c部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4 6 {$ J; o% B* V' i! _
模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,1 `5 ?# d2 B3 N' @, U
“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
% `8 _1 z4 ]0 v5 I5 ~; c自动化变量“$* ”需要两点说明: : U. k! E. R  K0 @9 y
?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发
- f& J' L, }( f/ v生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后/ Y3 K, [' h  @% e+ O: p
缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”( I6 m2 C6 u9 Z7 |
则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make; _0 Y. q9 b$ v1 Y% @" ]: f
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通
3 ?: l; Z: |: q9 d# D常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避. M" g! ?6 Y9 u- A7 B. A* k
免使用这个变量。 : C5 _# e9 r) [$ A
?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量
5 J5 ~, e2 a4 g! C6 z0 O为空。   W5 Y2 w( P0 o/ p+ k, G
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
. F5 {3 q/ r$ n5 A& E以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
% l4 U1 b  l$ D) y9 X5 f2 a- K则实现了只将更新后的.o 文件加入到库中:
, j1 a- G) H8 G' n* N$ J* Z
: h# e! y9 e0 K) a0 U     lib: foo.o bar.o lose.o win.o
, F1 X  V+ n/ |% D% k  I# X, s3 l             ar r lib $? ' K0 ?. R& u  l4 C& j- v% ?
9 F7 @1 G5 ]+ T4 W9 A, U/ r
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。" F" r1 q3 Z! M
而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”, n+ O2 @0 \8 K2 `2 d6 B, ]
或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
* g* t0 A* p0 Y" N  |# S+ B7 B中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可
6 {+ I/ }" S4 w( ~1 c8 l参考  8.3  文件名处理函数  一节)。
: ]; d9 {# x5 d; d, \* |2 f% Q
$(@D) % G0 d9 x" X4 `7 l- u" p
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”
4 r* d; [, q9 h/ `/ o的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函/ W- W3 T/ t/ d+ @% D3 S
数“dir”的区别! . U, `6 j8 |' o- f6 F0 f
$(@F) * x( b! b! f5 c* w
目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为+ B8 v$ ?1 g/ D* K1 B
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir % H, C, O$ ~' T
$@) ”。
* c, g' ]5 }$ L$(*D)
$ W1 f' E# u' Y  Q7 w2 L) s$(*F)
. Q" `. b* x. F, K/ a+ V分别代表目标“茎”中的目录部分和文件名部分。
- Y9 Y% V1 C" z1 y/ D5 u2 C7 i# t$(%D)
7 }, M2 l* m* M; @$(%F)   O& Z# [+ [8 N! k: K7 ~# ~
当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员8 Z. S6 D5 V& G6 u5 _9 C
“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。
% b- _1 Q/ p# O4 H$(<d)
: i+ d8 _9 Q  I6 E$(<f) ) S' v# ]9 m% |( d8 R. i  U! b+ U# _6 I
分别表示规则中第一个依赖文件的目录部分和文件名部分。 - z0 E, ~  H: s6 ^
$(^D)
/ g, M8 `" s: P, S8 ?' V1 \0 F. {) c$(^F)
; T5 I0 O2 ~; e& d; n+ @分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 ) t! i; S0 G( m2 ^' ^' w. |& Q
$(+D)
& R9 q' I/ S' V5 e$ ~" f$ ]$(+F) " x/ D  S& ]+ h/ t9 }
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。
  v" T' n& L, j: c$(?D)
( F6 j0 D) y7 [% P" s$(?F) + L0 {. y; l9 Y/ Y
分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了
7 a6 J1 z. T* p2 B. G4 s: L" Q“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于( `# m' t7 {: i8 a
自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我. G. y$ S( }: S1 B
们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
9 ~4 ?6 {  n  f因为自动化变量本身是一个特殊字符。
8 V$ }4 T% R( D# c% C7 LGUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
  O0 D3 d2 e4 q- L# ~2 c3 z" `! X用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
% \" U0 [  K. M(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
! `: O1 E- g' E" `  ]* ]2 j录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件$ c4 ^. g9 p1 t; i& n1 ^, l- t
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make
3 W& k" ?, n+ u$ |1 Y7 x8 U. r对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
  F* S2 z) z$ ~make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。 ! S5 @- k. Q9 [' p7 }( w
自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用
' X9 j& d- w+ T) ^6 M$ sGNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一" G2 N' t8 E$ w' d) @7 f
特性
$ Z) Q# e; D) H! h  M

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-26 22:36 , Processed in 0.064804 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表