一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

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

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

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$
% n' ^% t# K, S

8 Y, H' }) e; T5 Z" q7 o自动化变量 , {. u1 A) n$ D9 _7 w! j, w, }
模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
( F8 K; b- o) \一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
9 P7 X+ \9 d2 [% B  Y( [意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 * e# |2 H' q, |5 L/ a4 X
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写/ l) `8 S' h2 e* D$ P$ m9 e5 Q
正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时4 `/ n8 f  K9 g; A1 a/ `
源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量( C5 m) ]+ l+ ~8 o- y  G& k2 `
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 ( E3 {2 w2 A6 x; t% u# H
下面对所有的自动化变量进行说明:
6 G2 H: I1 J% Z. i2 L$@
6 @9 N/ b7 o2 C8 x4 N! Q表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
! U) j, f' [+ |) S6 O0 a文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式$ U# x$ x& Y+ a8 y
规则中,它代表的是哪个触发规则被执行的目标文件名。 2 A, E  D* e+ L: q
$%
% a' t2 r3 K( G当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则& Q. n0 Z* }+ b% p0 X4 a  D' U& Q
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。
7 k; N9 I) g2 c如果目标不是静态库文件,其值为空。
5 z/ z6 b( ^9 ?5 X9 H1 [  U$<
  b& G8 y0 J" W9 h6 P6 y规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表  N. O9 O5 z4 ~& K
由隐含规则加入的第一个依赖文件。
6 f/ ~5 W( H) \6 {% A$?
. k6 ?" q4 I+ D3 D( X" k: B/ |3 ^& B
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。 , G. b) P! S4 z+ y! U
$^ 8 i+ @3 w' m  U9 X; H+ b8 D9 {
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的9 g6 ^3 W  M8 J4 n
只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量5 A& @' f2 S- D0 v- L$ A8 s4 |  I4 }
“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。 ( [/ y" I, D/ H/ e
$+ 9 {. \; x2 }2 W- M  Y; R1 T% G, z
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库
2 w9 m9 k8 m. b) z# y4 v的交叉引用场合。
1 I6 R4 ?/ q' q# r! n0 u/ |! k$* & {: |+ k$ `' z% n
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的# _& a0 x7 j9 m) V  B  ~
部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4
- W# Y& }+ J" a模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,( h% ~5 S* q/ Z) O  e  p
“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。 ' p0 Y; [8 d8 B7 w( U1 x4 B
自动化变量“$* ”需要两点说明:
5 L0 P9 p# @0 Z* j?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发+ B3 t6 D0 M9 U
生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后
1 X* N. u5 G+ B! ^0 w. a缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”
# u2 N" t1 v% A0 C1 a' k, C则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make
9 n! x" {" Y/ m& s' r对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通
, S. B% N# h& J: N% n常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避& l- {) M! w2 n% D7 e" T/ T# x
免使用这个变量。 / w: t' E* h! B2 y% {9 K9 g
?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量1 f+ u! ~( L+ _- t. {0 |
为空。
) B, Z3 Q! [0 F& u8 Y% T自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
; }4 r! |) z9 U以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规7 R( B2 C; e: Q6 b; R! l
则实现了只将更新后的.o 文件加入到库中: % \  }- x9 i8 G3 D

( W- }9 ?+ `$ s5 g" m3 E  V0 i' S/ R& H     lib: foo.o bar.o lose.o win.o & {8 b9 Y4 @2 b+ g' y
             ar r lib $? . c3 ?6 n0 h6 i; F

4 ?& P. b9 p. Z/ ^% T0 I以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
- `3 R0 Y% ^: ~" _" K而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”
  t% s; v8 ~6 G$ v或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
# F6 y/ S3 H  j# g9 L中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可* [9 w3 e  Y  z' ^6 V4 P" m
参考  8.3  文件名处理函数  一节)。

$ h0 ]' l0 d. [6 C$(@D) / [- y2 C6 U8 I! r
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”
8 \, r  h1 T, H9 n的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函
0 b9 K  ~+ Z" P4 c数“dir”的区别!
+ `: j! G. C9 C- [; G$(@F) 3 G/ U5 t0 R3 P
目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为3 U6 F1 I, I- i/ E  U* h
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir . K9 \- I7 j# u4 b, g
$@) ”。 : L3 u. }( l: Q
$(*D)
0 H) o/ Z: u5 [1 }8 L$(*F) ! W3 ]6 S4 p3 Q* k. \
分别代表目标“茎”中的目录部分和文件名部分。 ; \" E; m/ C1 _0 p
$(%D) & ?/ U/ t8 N4 f
$(%F) . Z& @+ `8 r! l0 F
当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员
$ s0 ~5 h) t, T4 g* |0 X“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。
+ W* L/ S* C8 P& Z& `) A$(<d) ( J$ S" m6 G7 I  P
$(<f) & e: ^, \( h- T9 a; X1 [8 D* i' u
分别表示规则中第一个依赖文件的目录部分和文件名部分。 - `' s  s0 i$ A# j
$(^D)   Q. X/ @) l( I0 s) c* s5 j
$(^F) 9 ]8 w2 d; ^8 H  H
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 3 V* T" h/ H$ |. u0 c1 E. T0 g
$(+D) 0 c- ?6 b& B. x
$(+F) / c% ?# l0 ]2 ]: m+ \
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。 5 \& b8 ~1 x5 h5 k5 p8 T6 V
$(?D) , |0 H. B2 U% r9 q! G8 v: `4 b
$(?F)
  R. n0 y5 z0 ?8 l分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了, l& U6 o3 z! E4 W. t' G* B$ R( \" l
“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
9 O. V, E$ w! F1 Y9 L自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我. @% z2 W! M2 {3 ]
们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,8 j; H0 Q+ M' B. t0 ^$ |- l
因为自动化变量本身是一个特殊字符。
( O- d3 j- u5 H+ KGUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引' x- c  d" n8 l' @+ O! ?
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
8 e3 d6 c7 M! c5 l* a! ^7 \3 [(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目! V* B# b4 f, T
录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
' ]7 E6 |: Z7 }7 G) M名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make
$ P3 [5 W3 r0 q2 I对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
5 H) ~# S7 F& D; M, ~6 c8 E; O, ~make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
; r4 C+ A  r0 O  s: N% M3 d自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用  z9 l6 Q5 ]% v- j0 b, c: t5 E
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一
$ j4 q) C$ ]# z特性

! E( d6 M" u- v9 ^6 t% s

本版积分规则

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

GMT+8, 2025-4-28 09:11 , Processed in 0.056573 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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