一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3830|回复: 0

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

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$ 5 a9 v: @* y3 o# `3 W& o/ t
! w) ^8 a( d" _& S  p
自动化变量
7 Y; C$ U, ^0 x0 ~; h模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这% C* ?% v/ W. H7 P
一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去$ F, l0 ]9 c) `! Y+ ?) M
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。
* [7 s2 e% F1 k( E6 e* o' ]假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写( Z# s% d6 L3 N- |& e
正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
& v* e# d/ t* M; o0 f! O, k" B* s源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量
7 T6 v6 Q* t' O5 i/ A) ^2 I的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 1 B! C# D( ?1 O# R; p' J  p& o0 r
下面对所有的自动化变量进行说明: . S  k+ o; }/ s4 i7 K
$@ 9 e' T! V: e; X. K( p5 R
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为9 k. x# k( w0 v
文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式
2 j$ I% G" W" v规则中,它代表的是哪个触发规则被执行的目标文件名。 $ p& D- D& E8 O& E0 G# o* c2 a
$%   {' B& z8 S# ~- q  ?8 h: w
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则5 H% X  l& ~1 t  a) A
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。. p2 a8 u$ p: U
如果目标不是静态库文件,其值为空。
& i$ N: T8 T! Y$<
' H& ~7 d) Z+ U6 ?7 D: q规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表- u5 f5 P8 T; e; n. C  U
由隐含规则加入的第一个依赖文件。 : m* |6 G: B: H: q! u
$? ) E5 F! t% {) m* R' f
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。
! ]+ F# S6 Y! `6 @$^
5 W* x: y0 w2 D规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的
6 F0 t% ?2 E% X( j只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量* i5 D# n! v, C1 v
“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
3 d% Y% p% {- g+ T4 L0 ?% W$+ 0 A0 v) Z) X6 E% \# o3 S
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库. B  N# {4 S* [' C9 q
的交叉引用场合。 ) ]! v* p  W/ U" s$ t
$* ( }) n% X# ^, e$ B& ~6 l" `
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的
  B" _! {  q1 K) D, q" P9 ^部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4
$ L- X; [2 q1 Z" h3 r模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,5 q' _# R0 Q! [3 e" E
“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
' K" E. A/ S1 ~3 z. `% G6 C' V自动化变量“$* ”需要两点说明: & R) M! {) L3 W5 _5 g: Y
?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发
0 o" B3 _* t3 {: P2 X! ?3 [生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后
$ b6 B, J2 ~& I; J; l$ y9 V缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”
6 y  T8 O$ D% S& [: T! T则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make4 J/ ~- \) |0 J' d8 H
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通7 |  {" o5 G, z' K$ y
常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避
. E0 I. F, N; D, C4 {免使用这个变量。
+ r- q2 d) R8 e: q?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量
: h) Q! w0 x4 r( G6 l为空。 $ w4 @! S4 ?6 P! c; ^4 E
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
6 [: x7 G  q0 Q6 E- C以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
7 A9 M, r* E* X) j# _则实现了只将更新后的.o 文件加入到库中: 4 c" t1 L+ r; a" _) o( W
* {8 W+ }% l- R9 F6 s+ w
     lib: foo.o bar.o lose.o win.o
8 q5 }! o: i# ?3 \( W2 e% a# B             ar r lib $?
8 b; _1 q; c4 |/ u' C# v; I
7 |2 y$ [: e* B% e( E. j) n以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
2 f6 V6 |7 [. z7 O而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”2 \( ]) a( ~; b  C5 s" S# O, T# Q
或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
$ |" [$ N. a. z3 u4 Y8 g# C4 J中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可1 D7 F3 P! `* K4 d" Y
参考  8.3  文件名处理函数  一节)。
/ @: B9 u6 f. L/ W
$(@D)
6 n. f2 @$ o3 R) {表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”4 N+ r4 o% I3 P7 o) }& e& W
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函
5 O. o) ~; K! p* n  ]9 p# ~数“dir”的区别!
/ y. K) x' `6 f7 X$(@F)
! z# j1 z4 L; d+ f目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为1 F2 b& n9 M* j5 }+ T* Y+ i: Y
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir & ~$ }8 u' H( G! q7 m3 F* S6 `$ v- l
$@) ”。
4 K! u! h3 W$ C% D" W: X3 d. K6 K. |$(*D) % x) P* j! I- R+ e/ K; d  K
$(*F)
: m7 |, O; r" i- }: Z( M& s  n分别代表目标“茎”中的目录部分和文件名部分。
  {7 Y# J# Y& o$(%D)
/ V$ E8 x: p/ t* _$(%F)
9 P- n( G6 ?& a- \) t; b% j& M当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员
' D# x* q& Q* P% y! p“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。 # b3 m1 X2 A% o; }2 K
$(<d) ( P% j3 c  r+ ?, w9 p& D
$(<f)
- h& d2 e: f" \. d7 |分别表示规则中第一个依赖文件的目录部分和文件名部分。
0 G! y1 ?* [7 `7 t+ T1 B( D% h+ x$(^D) 9 d" z4 ?6 w# c! N# E/ x
$(^F) : x0 ]4 a; A- ]* u6 W% ^
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 + W- R: L$ E6 a# ~9 e
$(+D) % i# r% V6 T6 X8 F- K# f4 E) [
$(+F)
0 g- h2 Z1 U, V: u3 i分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。 , a- ]9 t( C! t8 J7 s$ |
$(?D) * a( J7 O) z* V
$(?F) 4 i# m7 P1 v: u/ q
分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了
% b2 n$ G, U2 K, b0 r: f“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于- q; ]$ ?6 W4 a- k% c! n! T
自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我
9 W( d7 W2 O8 G们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
5 l1 E- f3 q) v2 A! \2 [, {5 [因为自动化变量本身是一个特殊字符。
& D! J) l0 b8 X& A" }; v! p+ X& qGUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
$ J/ E/ M& m5 n4 y3 d用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
8 q9 w. Q4 n" g3 c0 U/ V' B/ Y(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
7 F0 ~; t: Y( N6 n) B6 E录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件; j0 N& F9 q# j6 Y9 l! C- B9 W
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make3 K* n4 i2 g& M7 G7 O9 Q
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN - `% J- o9 q. J/ X7 h
make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
8 S/ P( r, A& @% p4 v+ `' f6 }自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用8 R  Q( C! M6 Y* C- E
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一0 q1 b/ u, ]" y0 e# Y8 J
特性
: m8 Q% P  o. r( h. L5 Q

本版积分规则

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

GMT+8, 2026-1-12 05:15 , Processed in 0.028742 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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