Makefile学习之路(2) — Makefile的变量和通配符
一、变量
Makefile 也支持变量定义,变量的定义也让的我们的 Makefile 更加简化,可复用。
变量定义一般采用大写字母,赋值方式像 C 语言的赋值方式一样,如下:
A = HelloWorld
变量使用即取值时使用括号将变量括起来再加$
符,如下:
echo $(A)
编写如下Makefile
使用make命令执行,可以看到,其实他更类似与C语言中的宏定义
另外,我们可以在echo的前面加上@
符号,让该命令不显示出来
执行make命令可得
二、变量的分类
在makefile中有两种变量:
1、即时变量:A := xxx
2、延时变量:B = xxx
使用:=
表示即时变量,它的值在定义的时候已经被确定了;
使用 =
表示延时变量,它只有在使用到的时候才确定,在定义时并没有。
编写如下Makefile
A := $(C)
B = $(C)
C = Hello
all :
@echo A = $(A)World!
@echo B = $(B)World!
执行make命令如下所示,可以看到,变量A在定义时就获取C的值(此时为空),所以A为空,而变量B在使用的时候才获取C的值,所以得到为“Hello"
然后我们将Makefile再修改一下,将变量C的定义放到最后:
执行make命令,可以看到,B依然取到了最后C的值,这是因为make在执行时会先把整个Makefile文件读进去解析里面的变量。
三、变量的修改
直接使用=
和:=
进行修改,编写如下Makefile
A := $(C)
B = $(C)
C = 123
A = $(C)
B := $(C)
all :
@echo A = $(A)World!
@echo B = $(B)World!
C = Hello
运行,A被修改成了延时变量,B被修改成了即时变量
然后还有如下变量定义符号:
?=
:延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+=
:变量附加, 它是即时变量还是延时变量取决于前面的定义
编写如下Makefile
A := $(C)
B = $(C)
C = Hello
C ?= 123
A += World!
B += World!
all :
@echo A = $(A)
@echo B = $(B)
执行后可以看到,C的值并没有被修改,提示A和B的变量类型也没有被改变
另外,我们还可以在执行Makefile时存入变量,如下所示,注释掉C的定义
执行不带C变量定义和带C变量定义的结果如下;可以看到C的定义是生效了的,而且是最早定义的。
四、 通配符
编写Makefile和三个C文件如下所示,gcc的-c
参数表示只编译不链接
然后执行make命令,运行可执行文件
我们可以看到,当前只有三个C文件,编写的Makefile已经不少了,假如一个目标文件所依赖的依赖文件很多,那样岂不是我们要写很多规则,这显然是不合乎常理的,我们可以使用通配符,来解决这些问题。常用的通配符如下所示:
%.o
:表示所有的.o文件
%.c
:表示所有的.c文件
$@
:表示目标文件
$<
:表示第1个依赖文件
$^
:表示所有的依赖文件
修改后的Makefile如下所示
hello : hello.o william.o like.o
gcc -o hello $^
%.o : %.c
gcc -c -o $@ $<
clean :
rm -rf hello *.o
执行make命令,得到同样的效果
另外,加入变量,Makefile可以修改为:
OBJ = hello.o william.o like.o
hello : $(OBJ)
gcc -o hello $^
%.o : %.c
gcc -c -o $@ $^
clean :
-rm -rf hello $(OBJ)
执行效果如下
五、附录
上一篇:Makefile学习之路(1) — Makefile的引入及规则
下一篇:Makefile学习之路(3) — Makefile的函数