Makefile学习之路(2) — Makefile的变量和通配符

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的函数

猜你喜欢

转载自blog.csdn.net/qq_38113006/article/details/111824648