刚开始学习Make教程:https://makefiletutorial.vercel.app/#/docs/fancy-rules,里面有个sample:
objects = foo.o bar.o all.o
all: $(objects)
# These files compile via implicit rules
foo.o: foo.c
bar.o: bar.c
all.o: all.c
all.c:
echo "int main() { return 0; }" > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
执行之后结果如下:
echo "int main() { return 0; }" > all.c
cc -c -o all.o all.c
touch foo.c
cc -c -o foo.o foo.c
touch bar.c
cc -c -o bar.o bar.c
cc all.o foo.o bar.o -o all
疑惑对于traget: all的话,依赖顺序不是foo.o -> bar.o -> all.o吗?为什么执行顺序和预期不一样呢?难道是依赖没有顺序的?后来查询ChatGPT3.5,给出答案是: 所以是隐式规则在捣蛋啊!后面我将Makefile修改了下:
objects = foo.o bar.o allwhy.o
all: $(objects)
# These files compile via implicit rules
foo.o: foo.c
bar.o: bar.c
allwhy.o: allwhy.c
allwhy.c:
echo "int main() { return 0; }" > allwhy.c
%.c:
touch $@
clean:
rm -f *.c *.o all
发现了一点猫腻:
touch foo.c
cc -c -o foo.o foo.c
touch bar.c
cc -c -o bar.o bar.c
echo "int main() { return 0; }" > allwhy.c
cc -c -o allwhy.o allwhy.c
touch all.c
cc -c -o all.o all.c
cc all.o foo.o bar.o allwhy.o -o all
rm all.c all.o
顺序这次OK了,但是Makefile竟然创建了all.c 和 all.o,最后又删除了,因为隐式规则里面加了target all依赖于all.o。但是为什么两次创建all.c和all.o的时机又不一样呢?