Makefile 的自动化变量

Makefile Automatic Variable

在规则被执行时,规则的目标文件和依赖文件和书写 makefile时可能存在不一致,有两种情况:目标文件和依赖文件可能不是存在于当前工作目录(通过指定目录搜索目录,make可以在其它目录下找到指定的文件);在模式规则中,规则的目标文件和依赖文件都是代表一类文件。对于这两种情况,在命令中显然不能指定文件名,否则make将提示错误(找不到指定的文件)或者失去模式规则存在的意义。为了在命令中解决通过指定文件名而带来的错误,需要在命令中使用自动化变量。

makefile 的自动化变量(automaticvariable)的值由具体的规则来决定。不同的规则其所代表的目标文件名、依赖文件名不同,在 make执行过程中,自动化变量获取的值根据规则的目标文件和依赖文件的不同而不同。

注意:自动化变量常用在规则中,用在其它地方时,其值是不确定值。故建议仅用于规则中。

自动化变量列表

 自动化变量 自动化变量的目标部分 自动化变量的文件名部分
 @ @D @F
 % %D %F
 < <D <F
 ? ?D ?F
 ^ ^D ^F
 + +D +F
    注释1 |D |F
 * *D *F

注释 1 :如果没有特别说明,依赖通常指 normal 依赖,不包括 order-only 依赖。order-only依赖使用管道字符(|)和 normal 依赖分隔。

$@
1 代表规则的目标文件名。
2 在模式规则、多目标规则中,它表示的是触发规则被执行的目标文件名。
3 如果目标文件是一个文档文件(.a),代表文档文件名(非文档文件的成员名)。

$%
1 规则的目标文件是一个文档文件(.a)时,代表文档文件的第一个成员名。
2 如果目标文件没有指明文档文件的成员(指明的文档文件 1.a(1.o 2.o)),其值为空。

$<
1 规则的第一个依赖文件名。
2 如果是隐含规则,它代表通过目标指定的第一个依赖文件。

$?
1 所有比目标文件更新的依赖文件列表,使用空格分隔。
2 目标的依赖中可以有重复的依赖文件,变量 ? 的值会去掉重复的依赖文件。

$^
1 规则的所有依赖文件列表,使用空格分隔。
2 目标的依赖中可以有重复的依赖文件,变量 ^ 的值会去掉重复的依赖文件。

$+
1 规则的所有依赖文件列表,使用空格分隔。
2 目标的依赖中可以有重复的依赖文件,变量 + 的值会保留重复的依赖文件。

$|
1 规则的所有 order-only 依赖中存在,而 normal 依赖中不存在的依赖文件列表,使用空格分隔。
2 如果规则没有 order-only 依赖,变量 | 的值为空。
3 如果规则的order-only 依赖和 normal 依赖相同,变量 | 的值为空。

$*
1 在模式规则中,它代表目标文件的茎(stem),茎是模式字符(%)所代表的部分。
2 当目标文件名中存在目录时,茎包含目录部分和模式字符(%)所代表的部分。
3 假设文件名为 dir/a.foo.b,当目标文件的模式为 a.%.b 时,$* 的值为 dir/foo。

在自动化变量中,@、%、* 是对目标文件的操作;<、?、^、+、| 是对依赖文件的操作。
在自动化变量中,@、%、<、* 是代表一个文件名;?、^、+、| 是代表文件名列表。

make 提供的基本自动化变量获取的值是完整的文件名(包括目标部分和文件名部分),还可以通过在自动化变量后面加入D(directory) 或者 F(file)字符,表示获取基本自动化变量的目标部分或者文件名部分。

在自动化变量的结尾加入 D 字符(@D、%D、<D、?D、^D、+D、|D、*D)
1 代表自动化变量值的目录部分,但不包含目标部分的最后一个斜线。
2 文件名不存在斜线,其值就是 .(表示当前目录 ./)。
3 通过 dir 函数获取的目录部分包含最后一个斜线。文件名如果不存在斜线,其值就是 ./(表示当前目录)。

在自动化变量的结尾加入 F 字符(@F、%F、<F、?F、^F、+F、|F、*F)
1 代表自动化变量值的非目录部分。
2 等同于函数 notdir 的功能。如 $(@F) 等同于 $(notdir $@)。

示例 1
Makefile 文件的内容如下
# 1.o 和 test.o 文件存在,但是修改了 1.c 文件
%.o : 1.c test.c 1.h 1.c | 1.c test.c 1.h 1.c 2.c
 
    @echo $$\@ =$@
      @echo $$\% =$%
      @echo$$\< = $<
      @echo $$\? =$?
      @echo $$\^ =$^
      @echo $$\+ =$+
      @echo $$\| =$|
      @echo $$\* =$*

在命令提示符下输入 “make -R 1.o”,执行结果如下:
$@ = 1.o
$% =
$< = 1.c
$? = 1.c
$^ = 1.c test.c 1.h
$+ = 1.c test.c 1.h 1.c
$| = 2.c
$* = 1

在命令提示符下输入 “make -R test.o”,执行结果如下:
$@ = test.o
$% =
$< = 1.c
$? = 1.c
$^ = 1.c test.c 1.h
$+ = 1.c test.c 1.h 1.c
$| = 2.c
$* = test

示例 2
Makefile 文件的内容如下
# 当前工作目录下存在文件 makefile
# /etc 目录下存在文件 issue
# /usr/bin 目录下存在文件 make print
VPATH = /etc /usr/bin
GPATH = $(VPATH)

print : issue make makefile
      @echo $$\@ =$@
      @echo $$\^ =$^
      @echo $$\^D= $(^D)
      @echo $$\^F= $(^F)
      @echo dir =$(dir $^)
      @echo notdir= $(notdir $^)

在命令提示符下输入 “make”,执行结果如下:
$@ = /usr/bin/print
$^ = /etc/issue /usr/bin/make makefile
$^D = /etc /usr/bin .
$^F = issue make makefile
dir = /etc/ /usr/bin/ ./
notdir = issue make makefile

示例 3
Makefile 文件的内容如下
1.a(1.o 2.o) : 1.o 2.o
      @echo $$\@ =$@
      @echo $$\% =$%
      @echo $$\^ =$^
      @echo $$\+ =$+

在命令提示符下输入 “make”,执行结果如下:
$@ = 1.a
$% = 1.o
$^ = 1.o 2.o
$+ = 1.o 2.o

示例 4
# 当前工作目录下不存在文件 1.o
# /home 目录存在文件 1.o
VPATH = /home
GPATH = $(VPATH)

%.o : 1.c test.c 1.h 1.c
      @echo $$\* =$*

在命令提示符下输入 “make 1.o”,执行结果如下:
$* = /home/1

工作中,make会把warning和error信息输出到标准错误上,把这些信息重定位到文件里,需要先把标准错误重定向到标准输出上
命令是:make >info.log2>&1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值