一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

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

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

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$ 4 W" k& P/ Y/ X- F1 g
3 }3 Z3 a+ ~3 {4 V% `/ U( g
自动化变量
" h, {. u0 r3 I6 P模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
9 a9 u; N4 _; }, K, z一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去3 b$ D, \  R9 m
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 0 ?# _" H; ^1 q, K
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写' Y" |% T6 Q2 s1 T! c5 x
正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时. R+ n  G, t; u
源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量
' Q; X& q( V. k的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 3 Z. w; m0 Q, {& g
下面对所有的自动化变量进行说明:
( m. P, t0 h% b! Z0 w0 p3 `$@
$ J) _# q+ U4 \  S" r8 N表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
1 L! o  ^( g4 l0 n$ q1 c  v8 l. O文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式
5 K0 G0 R. f+ S3 Z  U- `$ e规则中,它代表的是哪个触发规则被执行的目标文件名。 ( O& p" t& k7 n) `/ W/ m
$% 7 N5 l* P) V, z" S
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则
4 m; r( F$ _2 x6 K4 F的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。7 Z2 e% a/ D; n: |
如果目标不是静态库文件,其值为空。
/ R$ G7 B% C! i! J$< 3 p, d+ v2 `) b' D
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表' o) x5 ?% a0 n1 L3 w
由隐含规则加入的第一个依赖文件。
8 u. A( q% J! ?$?
2 O4 I5 E5 R6 `( ^8 Y9 a
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。 ; v! x1 }. c  [6 c% j) A- C
$^ $ u5 g' s$ b8 N7 ], p( {6 I
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的, k( G# p0 ?7 a
只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量/ q9 M4 d$ {  b% s+ `( O
“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
6 H2 l! d0 }9 B3 w$+ : {# n9 k5 X1 L2 v4 a$ q0 Q# a. U) n, [
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库* f* ?7 o0 m$ a- o8 p' w! y
的交叉引用场合。
3 x3 F+ z- W3 B, G" T( c$* 8 ]$ \9 B# a* u- m/ d
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的
* w: W9 V0 u/ O1 h2 w8 y  M部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4 , e) ?8 z& ^" B3 l1 b( J
模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,& c, V0 z  P- W$ n
“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
# F5 t, [- n+ `5 i自动化变量“$* ”需要两点说明: 1 N- L7 [2 N! E; p
?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发
8 B- O- c. B9 h) a生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后
7 Q) l8 c* z: Z5 a; v6 @& o缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”: p7 @8 A& X0 N; F! t
则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make! z, s+ C( R0 q3 h- a
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通
- g8 n* B* e& ]2 O1 V, `3 h常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避% Z' q' C3 H! ~$ `7 S  e6 C" ~
免使用这个变量。
2 r) r( o7 g: D) j$ G* Y9 `?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量
# a) T+ H& r8 A* p( w- D为空。
/ C6 G* {" F: |自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新1 \0 H: W+ T0 B% _& U
以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
2 v4 [7 y) V+ d; O则实现了只将更新后的.o 文件加入到库中:
4 {) S" b8 g6 m6 S% k) S; [2 [" \$ T
4 B) Y: T! `& N1 ^7 P     lib: foo.o bar.o lose.o win.o : ], D5 m  w  d6 z3 V9 i& h
             ar r lib $?
1 H+ S; J. Y$ J! c# n( s ' L" F. Z1 o* H! p. n
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
" M& _/ Q! u: @& ^而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”
) X" a6 h& Z/ s! b- z2 f或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make, r$ [& H% F4 k* d1 K
中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可
9 \8 ^4 V* H6 ~" \1 |参考  8.3  文件名处理函数  一节)。
1 a6 G" |2 L) m5 p9 e
$(@D) 4 H' f( p8 C* g
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”5 u# h, `8 ?/ I; Z6 }$ L
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函' d! e" l; k9 Z3 E( h6 ~5 M
数“dir”的区别! 0 I  y0 `, b# a1 {' O
$(@F)
6 z# Q8 w7 U% c8 ]目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为4 |# \. R! B, @) p
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir 4 v1 b4 i0 I+ Z$ I
$@) ”。 / U- l% H  {6 `* `2 }. F; W  T
$(*D)
7 K8 C- V5 h( H' g1 B9 F' A: W( I$(*F) 9 b. Y+ g/ l0 T: d
分别代表目标“茎”中的目录部分和文件名部分。
6 i) b3 m/ R/ U, M+ j" W" l$(%D) . {0 b3 U5 _' n* u* Y" ?
$(%F)
) k) Z% z1 a- ^. H当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员" N0 F' H' b7 Y# \5 j: }
“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。 / n3 t  a0 a. U7 f' W
$(<d)
. p. m5 o! i1 s# w) n$(<f) 1 U& [$ k. P2 F7 q
分别表示规则中第一个依赖文件的目录部分和文件名部分。
7 Z! g6 m3 U" h. q  M$(^D) 3 N4 A, G1 O- v& S; T: v
$(^F)
" I: {: D! i8 i# n分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 # S1 y3 `8 d! F1 F2 T
$(+D) 4 S1 W4 s0 K/ n* A. B5 o: O1 K
$(+F)
; A$ C! z/ x/ X. p分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。 3 z6 u# e' }. ^& Z
$(?D) 7 U- o) K- R" a4 B  G
$(?F)
  P7 C4 C1 o2 n0 L7 h分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了0 e/ [$ r1 C" T; d- G1 |# q: }
“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
7 ~  V6 S6 b3 T. G7 t# N+ C$ M$ x自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我
' j  h8 G/ {3 E' J; F, E1 d们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
5 J3 I" b6 M( h) N9 Q. O/ p2 K6 j因为自动化变量本身是一个特殊字符。 7 t' `) j0 c) ]  l/ G
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引* M; r9 c* o5 l& B. i
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”; ~# V8 R& M7 O7 B& V: V' }
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
) V' v  h# E  _9 Z1 J; F7 k3 U: J$ D录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
# A2 {4 @. z! I8 H名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make) m/ A9 a/ R! Z6 I9 T3 `
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
# j; c' {1 X+ s6 ~5 G& H( Jmake对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
3 }) I; Z, Q7 O% H; k自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用: F+ b9 R6 v' j1 v' l2 j$ ^. @, a
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一# p, z; V, f" X- m6 C* s
特性

( b3 G! \: H/ R2 Z( Q

本版积分规则

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

GMT+8, 2024-4-25 20:35 , Processed in 0.054379 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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