ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Makefile初学之谜之隐式规则

2026/9/9 1:56:23 拓冰建站 浏览量
Makefile初学之谜之隐式规则

 刚开始学习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.call.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.callwhy.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的时机又不一样呢?