1. Makefile中:=, =, ?=和+=
“=”是最普通的等号,在Makefile中也是最容易搞错的赋值等号,使用“=”进行赋值,变量的值是整个makefile中最后被指定的值。
举例如下:
x = A
y = $(x) B
x = AA
经过上面的赋值后,最后y的值是AA B,而不是A B。make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。
“:=”表示直接赋值,赋予当前位置的值,变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
举例如下:
x := A
y := $(x) B
x := AA
经过上面的赋值后,最后y的值是A B,即根据当前位置进行赋值。相比于"=",":="才是真正意义上的直接赋值。
"?="表示如果该变量没有被赋值,则赋予等号后的值
x ?= A
如果x在之前没有被赋值,那么x的值就为A
x = B
x ?= A
这种情况下,x的值就是B
“+=”和我们平时写代码的理解是一样的,表示将等号后面的值添加到前面的变量上
x = A
x += B
x的值是A B
2. Makefile中$^,$@,$?和$<
$^ 表示所有的依赖文件,以空格分隔。如果依赖文件中有重复,那么这个变量会去除重复文件,只保留一份
$@ 表示目标文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
举例如下,目录中有这些文件
$ ls
hello.c world.c main.c Makefile
Makefile文件如下:
main: main.o hello.o world.o
gcc -o main main.o hello.o world.o
main.o: main.c
cc -c main.c
hello.o: hello.c
cc -c hello.c
world.o: world.c
cc -c world.c
clean:
rm *.o
rm main
改为用上述符号进行替代后,Makefile文件如下:
main: main.o hello.o world.o
gcc -o $@ $^
main.o: main.c
cc -c $<
hello.o: hello.c
cc -c $<
world.o: world.c
cc -c $<
clean:
rm *.o
rm main
下面的命令表示把有更新的依赖文件重新打包到库lib中, 如果只有hello.o更新,则$?代表hello.o, 如果hello.o world.o都有更新,则$?代表hello.o world.o的集合。
lib : main.o hello.o world.o
ar r lib $?