一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

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

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

[复制链接]
发表于 2017-5-4 09:05 | 显示全部楼层 |阅读模式
makefile中的自动化变量 $@,$%,$ ! q. n& h4 @, y) j8 X" \6 K

1 n, J: J4 ^  X) k- t  p4 v自动化变量
$ Q1 L+ f/ n* P% ~' j' I5 q5 v1 o模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这7 `: d/ f9 Q4 `/ _5 L, P
一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
- X; R) U7 Q% l意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 & m3 ^- C, `& V  o
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写
7 P5 L! `9 ?% \1 `正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
/ V, z- e5 }1 u" q6 r源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量/ V$ Z! Z* l7 V! @( \, m
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。
( B: A8 O$ d9 ^0 o. d; w$ d下面对所有的自动化变量进行说明:
4 C" O# l' {" B$@ 6 p0 Y; o) `9 [3 Y' A: r  E
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
- f/ O' S3 F" c' d1 v文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式3 b- X5 n' E1 h* p
规则中,它代表的是哪个触发规则被执行的目标文件名。 + F; J' d  a$ |
$%
2 F: Q( V. U9 z9 {. j当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则  F% l: c( _- [, f
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。; k. x( E/ u9 {3 }
如果目标不是静态库文件,其值为空。
% U- m% \4 c$ P% x$< $ R' Y+ y4 X. |* Z& v
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表
% Y( p4 I. I2 p5 @由隐含规则加入的第一个依赖文件。 * A9 u* k! n1 S8 [5 U4 N
$? ( J) ~& C- N- V: }/ s: p. k9 \1 W  p
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。
; S& O% y" I1 d5 h! Q7 A+ c$^
/ i; k( W7 w1 o规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的5 I+ h; B: I$ `" N* b+ a. ~& g
只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量
0 w" C/ t* y6 w- p/ }+ Y+ \* [/ A“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。 . f' ?( M) k! y  ~6 B* z
$+
" K  B- ?3 P( O' q& F# P% ^类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库8 r! N. g6 K. f+ `! O
的交叉引用场合。
% |2 ?$ ~8 @) g. t2 O$* - j2 }# x; d3 J+ ]  M9 R6 o& v/ y
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的3 @7 L( d0 F& @5 @0 e5 L2 `: F
部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4
" M0 U( N! e1 G模式的匹配  一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,
, t0 @' j, b0 i% K0 M( @“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。 8 G& }- A/ T: |" p
自动化变量“$* ”需要两点说明: , [2 e, U0 R$ ?/ s: G  ]
?   对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发
: [- e* n" `7 W; s! M- I5 C# ^生改变。此时,如果目标文件名带有一个可识别的后缀(参考  10.7 后( R& c5 q" r. H2 D4 U
缀规则  一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”8 S; T! j6 Q* k# n4 N! N# j! T0 y
则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make3 M& ?% @, x" _6 W; _' m2 m! {
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通- \1 V  S9 U6 l, T. e( ^, h
常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避
# n) l/ P5 G! a2 j8 B" [  N免使用这个变量。
( p/ {% |  L: \8 d/ R?   当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量7 N( U0 g; }8 p8 w* x
为空。 ( F9 S$ p- `' U$ y3 D4 X# h
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新+ v9 I# b. H  M. t- y. C4 e' v
以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
6 j0 U2 C3 k& N. B( C, c6 L% H; J则实现了只将更新后的.o 文件加入到库中: 8 M2 H, A% ?0 o0 ?5 h3 U

: H6 f. s9 v6 P9 a, o0 R: S* C     lib: foo.o bar.o lose.o win.o 0 J( J2 k: v5 v* B* }
             ar r lib $?
* N! R+ S. v: L: ^. S * ~, C! |; u6 A- @* A
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
7 ^4 O7 e" v6 y+ d$ d而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”
; Y/ r+ U! J0 v1 G1 y6 z/ {8 n5 d或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
/ G! V1 g0 I- O9 `2 z中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可7 Y1 \9 B2 c$ R. v
参考  8.3  文件名处理函数  一节)。
% d7 q+ J, ~8 m- M
$(@D) ' ?+ j. u$ V6 c" q
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”+ V( _  {, i4 b) Y9 z/ C
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函+ x6 a6 h0 k0 V- z  l8 F. Q
数“dir”的区别!
# v. ?8 z6 Q7 P$(@F)
+ U8 b; v/ i7 Z3 I' m: ~目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为* ~) K: y5 y0 c4 N+ y$ b: f- D
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir
4 T" k, h9 p; C* }- F* D# K9 y! k$ \$@) ”。 $ e( s9 K' e" l' D; S2 W7 ?& W: y* O
$(*D)
0 C2 p8 o% a& h$(*F) 2 u, `8 O& h0 q. b4 W3 ^5 P& Q
分别代表目标“茎”中的目录部分和文件名部分。
1 r$ j( f" [% n7 ~# ~$ A# R$(%D)
6 i7 g3 n: m) h$(%F)
: {1 ~- O5 b7 a* I$ f当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员7 }0 P; P/ O% Z& r: Z7 x2 T
“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。   S) n" g+ s3 |+ t/ |
$(<d)
1 B1 `; N2 M8 {0 p4 I' o% [$(<f)
: E+ G- E1 R$ g1 ^! v分别表示规则中第一个依赖文件的目录部分和文件名部分。 # P7 K0 V. v* K% K5 k4 ~
$(^D) 0 E" L. J, N( F8 z& Z
$(^F) - ^1 S* ^; ~+ y# p$ k
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。 / H# K* ]' _- m: ~% d6 I* }
$(+D) $ t7 d+ H( u- i( z3 o; U4 J
$(+F) ; ]: _, `* _2 y$ N. Z2 f
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。
( W' J$ D: O2 h' e$(?D)
' F4 x% {7 f. r- n$ l9 S) o$(?F)
7 X3 T  R( i! D1 x+ s4 {分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了, \- _" _3 V2 f
“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
5 q2 C% L% B; s( r& t# c自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我
$ [  V/ m/ ]$ k们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
6 |4 W) H0 m: M# o" H6 x因为自动化变量本身是一个特殊字符。   S- v5 Y2 t' d  W; L2 v
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
3 Z2 B' l! p  O( z6 e4 [: F用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”6 W; p5 C+ ^: R6 j! i1 I
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
' M% d# Y) M4 |# {, G3 \1 n; J1 I录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件+ c3 y! F$ p9 W  ?
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make6 y9 R: N! c6 F1 R& x$ E
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
% ~8 Q. L- w6 a& Y5 amake对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
. d$ K  S& |( S7 P3 }自动化变量的这个古怪的特性完全是为了兼容Sysv  版本的makefile文件。在使用! M+ ^% u$ R; ]/ ^' G; [
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一3 F  O% P  X. M, Z, Z
特性
2 i& K* L7 q$ f5 e" V" J

本版积分规则

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

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

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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