Makefile的$@、$%、$?、$^ 、$+、$*自动化变量说明

自动变量

含义

  • $@ :表示规则中的目标文件集。在模式规则中,如果有多个目标,那么, $@ 就是匹配于目标中模式定义的集合。
  • $% :仅当目标是函数库文件时,表示规则中的目标成员名。例如,如果一个目标是 foo.a(bar.o),那么, $% 就是 bar.o , $@ 就是 foo.a 。如果目标不是函数库文件(Unix 下是 .a , Windows下是 .lib ),那么,其值为空
  • $<   :依赖目标中的第一个目标名字。如果依赖目标是以模式(即 % )定义的,那么 $< 将是符合模式的一系列的文件集。注意,其是一个一个取出来的
  • $?    :所有比目标新的依赖目标的集合。以空格分隔。
  • $^    :所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
  • $+    :这个变量很像 $^ ,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
  • $*    :这个变量表示目标模式中 % 及其之前的部分。如果目标是 dir/a.foo.b ,并且目标的模式是 a.%.b ,那么, $* 的值就是 dir/a.foo 。这个变量对于构造有关联的文件名是比较有用。如果目标中没有模式的定义,那么 $* 也就不能被推导出,但是,如果目标文件的后缀是 make 所识别的,那么 $* 就是除了后缀的那一部分。例如:如果目标是 foo.c ,因为 .c 是 make 所能识别的后缀名,所以, $* 的值就是 foo 。这个特性是 GNU make 的,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用 $* ,除非是在隐含规则或是静态模式中。如果目标中的后缀是make 所不能识别的,那么 $* 就是空值。

比较$?和$<的区别

CC := g++
CCFLAG :=
DBGFLAG := -g
CCOBJFLAG := $(CCFLAG) -c

all:main
main: main.o f1.o f2.o
	$(CC) $(CCFLAG) -o $@ $?

%.o: %.c*
	$(CC) $(CCOBJFLAG) -o $@ $<

现在用这个Makefile编译如下文件:f1.cpp  f1.h  f2.c  f2.h  main.cpp,并生成可执行文件main,执行make,得到如下结果

g++  -c -o main.o main.cpp
g++  -c -o f1.o f1.cpp
g++  -c -o f2.o f2.c
g++  -o main main.o f1.o f2.o

可以看到,前三条都是执行的“$(CC) $(CCOBJFLAG) -o $@ $<”,只有最后一条执行的是“$(CC) $(CCFLAG) -o $@ $?”,也就是说$<是一个一个取出来的,一条一条分别执行的,而$?是集合,可以看到最后一条输出含有所有的依赖目标。

还有一点是$?为所有比目标的依赖目标的集合,这一点也很好证明,在刚才make的基础之上,执行如下命令:

touch f2.o

该命令会更新f2.o的时间,也就是说这时候f2.o比main新,此时,再次执行make,得到结果如下:

g++  -o main f2.o
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld 返回 1
make: *** [main] 错误 1

可以看到,执行编译时只使用了f2.o文件,所以执行失败。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值