一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

搜索
查看: 3395|回复: 0

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

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$ ; R! P# p5 M( g) D: w% ]5 o

; B; M9 E5 ~6 o# }自动化变量 : u. D6 f8 x" \" `/ q
模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
5 `: a5 B3 M6 C一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
0 W0 H1 n0 l5 R9 }: i. R意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 2 |9 r9 H" G; k1 z+ H
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写
9 S  ?; F% N" x% i正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
, n* P3 m) f$ o4 o源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量9 i& w$ B$ E% p( N' F
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 4 Z. i2 O/ [2 H
下面对所有的自动化变量进行说明: 6 Y3 m. Y2 K+ t( q
$@
( }! N" q+ W- E( B4 _2 h表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
2 ~  W' _& l: o) U/ D文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式# z4 m% R" M* z- V6 E% D2 A
规则中,它代表的是哪个触发规则被执行的目标文件名。
; Q4 o- o' S6 R: T0 K6 v* J( Z4 m0 g$% % F7 x. M1 h+ {! G4 Z$ b  j) Z& s% u, }
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则6 P% @" b7 y- o
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。
" p4 \3 N4 m4 L0 r3 u如果目标不是静态库文件,其值为空。 - ?. o$ ?6 h  p4 w) G& Z4 a
$<
. u. z5 K# Z$ X9 s% j8 d1 L规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表5 D" [7 l, ]  a% H$ |7 P
由隐含规则加入的第一个依赖文件。
. E+ d) s3 g+ F$ J8 X$? 1 g7 Y# {) s( U7 H* O* H+ [
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。
0 h+ Y1 D3 {* R! `8 N, i$^ ! U6 t9 F  n) |" n. R
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的
6 B( }1 d7 v9 q) L6 S. e; y只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量) {1 ^- Q; ]$ ?  \3 J! `
“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。 ( c3 [+ A+ r4 `: Z# E& n7 ?* Q
$+
0 N) Q1 G/ M2 Z6 X1 z* C类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库
: V: Q+ j3 q7 P/ [# f的交叉引用场合。
. V! x' u9 K, O; L; a/ J3 ~. [$*
/ Z6 V& ]8 M, B在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的$ i9 W* V3 \; u( @0 y9 E
部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4
+ W* ~. c, m9 m9 h模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,
4 f" j9 L) r/ B! ^) V: S“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
5 _  s  F7 C! e- B自动化变量“$* ”需要两点说明: , Y& w, _- f/ `
?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发8 X  S" r% D  P' k
生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后
0 L$ b9 C" w1 f4 P2 A; C) p缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”
0 o+ H- Q1 i1 E1 V) g* o7 Q则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make2 ~) F9 q& E( c
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通
" O/ \0 `2 v& ?. ^4 X常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避
5 o3 @- i2 ^( Z* H$ q% i4 J免使用这个变量。 6 F9 B& W5 p! S5 L* @1 s
?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量
/ B& A. j) s& _; \2 h为空。
) ]% h0 ^: c  }6 m4 g自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
) V1 N* T  L9 G; n6 _- ~以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
9 \# j! [; O) }6 H& N" B  q则实现了只将更新后的.o 文件加入到库中:
, ~0 L  C) N/ P$ |! I' s. f
- y2 M$ M  h# G  u7 C; U     lib: foo.o bar.o lose.o win.o
$ x, v; d7 c2 W0 ~- F; C             ar r lib $? 1 x4 j  K2 ?% i% r/ H# [" X
+ \! f, Y+ @0 c
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
3 x7 A+ \* A$ \7 u2 C  r而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”
" q( J* }. V( X9 |# R或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
( ]$ I1 B2 s: h- A中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可
, h1 I$ M. c9 I3 d, c* f参考  8.3  文件名处理函数  一节)。
/ N! @; j, f, c' D$ _
$(@D) - [6 Z( \& n2 v% r: c0 [$ y  a
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”' t1 L! b" F, L+ s
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函
5 P) p5 u" F: x+ \+ e数“dir”的区别!
5 U+ N0 Q$ G4 c& s) T1 U- j" Z$(@F) # g# b5 J$ `1 o  }. f1 e4 Q6 O* Q
目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为3 \# R3 E3 s! E, d# q$ S1 M
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir
; C8 N  k0 L3 M2 J. w$@) ”。
1 z5 v: K0 k) _! n# y3 h( s$(*D) ( M- c/ ?8 e8 O: ]% Y
$(*F) 2 K, y& i- T! R1 l  e" i
分别代表目标“茎”中的目录部分和文件名部分。 1 q7 q- }4 O3 e
$(%D)
0 t, S9 t2 |+ Q7 c4 H$(%F)
. z7 f! Y( V) f) F8 N3 \/ x当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员
" f. G) K7 |$ m. b5 `: N“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。 6 f2 B# ~1 o8 a
$(<d)
$ b$ g. K) k$ T& }+ N$(<f)   c" t4 a3 j8 s4 u1 _. L$ I1 G
分别表示规则中第一个依赖文件的目录部分和文件名部分。 9 x. J$ e  ?, k/ y% H
$(^D)
% @3 L" Z$ @+ ?$(^F)
) J0 G& r, X2 X" g) v' R分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。
; {! `5 ~  y, o) v$(+D)
8 h* V: l4 a1 M; m$(+F) 8 H0 [7 U+ V0 B, e) B& ?% I
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。 $ C' u- ?- a1 X" O
$(?D) 2 U+ _, r  L) a! Q4 k. H0 T
$(?F)
1 S4 X$ q7 x  Y& l' Z. f分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了
- O7 W3 n- C0 m; I. p) P+ u“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
4 m+ D: B4 Q% G1 H- m; m( }自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我5 f3 m" s# i( M8 q" C' X7 h6 F
们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,- W, {2 N3 a  i3 b
因为自动化变量本身是一个特殊字符。 % v" Q8 n8 |9 L* H3 Z7 e: j
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引& w" E* i+ Q$ H8 g2 e* W
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”; y9 R" m! g+ U# b$ j
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
% F/ G+ S* ^! S7 `录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
4 U, Q: ?# ]3 L1 e" |- H9 _名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make- q* C9 F9 W3 y& _) O3 {  E; f2 r
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN % w, e1 Q; m( R, B, B5 s
make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
4 L0 t8 H, k( e- |$ u  q9 H, |自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用6 O/ `% {1 s( z2 n3 W; _
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一
. O( s7 V3 [  Q. y4 {' ^9 q特性
7 M5 C2 `* K/ K. e8 L

本版积分规则

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

GMT+8, 2025-8-20 09:02 , Processed in 0.042894 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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