Makefile的语法
通配符(pattern)
现在我们有三个程序
a.c
#include <stdio.h>
int main()
{
func_b();
func_c();
return 0;
}
b.c
#include <stdio.h>
void func_b()
{
printf("This is B \n");
}
c.c
#include <stdio.h>
void func_c()
{
printf("This is C\n");
}
前面Makefile 的写法如下
test: a.o b.o
gcc -o test a.o b.o
a.o: a.c
gcc -c -o a.o a.c
b.o: b.c
gcc -c -o b.o b.c
此时将暴露出问题,如果文件所依赖文件很多,岂不是要写很多规则,这显然是不合理的。下面我们可以使用通配符来解决这些问题
test: a.o b.o c.o
gcc -o test $^
%.o: %.c
gcc -c -o $@ $<
%.o
:表示所用的.o
文件
%.c
: 表示所有的.c
文件
$@
:表示目标
$<
:表示第一个依赖文件
$^
:表示所有依赖文件
假想目标(.PHONY)
- 如果想要清除文件,在Makefile 的结尾添加如下语句即可
clean:
rm *.o test
执行make clean
则会清楚所有的.o
和 test
文件。
- 这时候问题又来了?
如果你目录下存在clean文件,则会出现如下提示
make: ‘clean’ is up to date.
很明显没有帮我们clean
掉文件
- 如何解决?
在Makefile 的最后,加入.PHONY
关键字即可
.PHONY: clean
变量(variable)
Makefile中存在两种变量:
- 简单变量,又称为及时变量
A := xxx # A的值立即确定,在定义时即确定
- 延时变量
B = xxx # B的值使用到时才确定
对于延时变量使用 =
表示,它只有在使用到的时候才确定,在定义的时候等于没有确定下来。
想使用变量的时候,使用$
来引用
A := abc
B = 123
all:
@echo $(A)
@echo $(B)
加上 @
是为了不显示命令本身
实例:
A := $(C)
B = $(C)
C = abc
all:
@echo $(A)
@echo $(B)
执行 make 能看到
:= # 即时变量
= # 延时变量
?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+= # 附加, 它是即时变量还是延时变量取决于前面的定义
?=: 如果这个变量在前面已经被定义了,这句话就会不会起效果,
A := $(C)
B = $(C)
C = abc
D = 100baidu
D ?= zhangsan
all:
@echo A = $(A)
@echo B = $(B)
@echo D = $(D)
C += 123
很明显看到 D 是等于 100baidu的,因为前面已经定义过了(D?=
前面定义过,则不会再起作用)
A := $(C)
B = $(C)
C = abc
# D = 100baidu
D ?= zhangsan
all:
@echo A = $(A)
@echo B = $(B)
@echo D = $(D)
C += 123
那怕通过命令行传入 D的值,里面的 D ?= zhangsan
都不会起作用
make D = 123456