在智能一点,全部使用自动化变量
obj= main.o foo1.o foo2.o
main : $(obj)
gcc -o $@ $^
clean:
rm -f *.o main1 main
$@
代表规则目标本例就是main ,$^
代表规则所依赖文件本例是 main.o foo1.o 和foo2.o
makefile也可以编译多目标文件,我们本例拷贝一份 main.c 命名为 main1.c,
obj= main.o foo1.o foo2.o
obj1= main1.o foo1.o foo2.o
var = main main1
all: $(var)
main : $(obj)
gcc -o $@ $^
main1 : $(obj1)
gcc -o $@ $^
clean:
rm -f *.o main1 main
结果是:
make
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
cc -c -o main1.o main1.c
gcc -o main1 main1.o foo1.o foo2.o
发现生成了多目标 main 和main1 。
优化后的makefile:
obj= main.o foo1.o foo2.o
obj1= main1.o foo1.o foo2.o
all: $(obj1) main
main : $(obj)
gcc -o $@ $^
$(obj1):%.o:%.c
clean:
rm -f *.o main1 main
下面显示一下 $^
和$<
区别:
obj= main.o foo1.o foo2.o
all:main
main: main.o foo1.o foo2.o
gcc -o $@ $^
clean:
rm -f *.o main1 main
编译过程是:
make
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
可以正确编译文件,
我们修改makefile为:
make
gcc -o main main.o
main.o: In function `main':
main.c:(.text+0x1c): undefined reference to `foo1'
main.c:(.text+0x21): undefined reference to `foo2'
collect2: ld returned 1 exit status
make: *** [main] Error 1
发现只有一个文件 mian.o 少了foo1.o 和 foo2.o。
all
作为Makefile的顶层目标,一般此目标作为默认的终极目标。 即使 all前不加 .PHONY,也会默认作为终极目标
以前很迷惑 = := 和+= 区别
obj= main.o foo1.o foo2.o
all:main
A=PPTV
B=$(A)
A=DSP
C=$(B)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo $(C)
clean:
rm -f *.o main1 main
结果是
make
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
DSP
操竟然不是 PPTV,
obj= main.o foo1.o foo2.o
all:main
A:=PPTV
B:=$(A)
A:=DSP
C:=$(B)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo $(C)
clean:
rm -f *.o main1 main
结果是:
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
PPTV
现在是我们想输出的PPTV了,
“=”
make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值
“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
要是下面你只输出什么me??
obj= main.o foo1.o foo2.o
all:main
A:=PPTV
B:=$(A)
A=DSP
C:=$(B)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo $(C)
clean:
rm -f *.o main1 main
这个结果是PPTV
因为B:=$(A)是即使展开,此时B=A=PPTV
obj= main.o foo1.o foo2.o
all:main
A:=PPTV
B=$(A)
A=DSP
C:=$(B)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo $(C)
clean:
rm -f *.o main1 main
这个结果是DSP
因为 B=$(A)值是A在makefile最后的值,本例中最后的值是A:=DSP
下面看一下 ?=使用
obj= main.o foo1.o foo2.o
all:main
A="PPTV"
A?="DSP"
B=$(A)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo ===== $(B)
clean:
rm -f *.o main1 main
执行结果是
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
===== PPTV
我们把A=PPTV去掉后结果是
obj= main.o foo1.o foo2.o
all:main
A?="DSP"
B=$(A)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo ===== $(B)
clean:
rm -f *.o main1 main
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
===== DSP
发现当没有定义A时,A?=DSP,有定义A=PPTV时候,就会等于PPTV,
A=
A?="DSP"
B=$(A)
我测试一下上面结果也是PPTV,因为A被定义为空,也是定义了,只是值为空。
obj= main.o foo1.o foo2.o
all:main
A:=PPTV
A+=DSP
B=$(A)
main: main.o foo1.o foo2.o
gcc -o $@ $^
@echo ===== $(B)
clean:
rm -f *.o main1 main
上面结果是:
make
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
===== PPTV DSP
+=意思是追加变量赋值。