原文链接:自动处理头文件的依赖关系
这篇文章详细解释了Makefile自动处理头文件依赖的问题,其Makefile文件如下
all: main
main: main.o stack.o maze.o
gcc $^ -o $@
clean:
-rm main *.o
.PHONY: clean
sources = main.c stack.c maze.c
include $(sources:.c=.d)
%.d: %.c
set -e; rm -f $@; \
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
原文的解释已经很清楚,不再详细分析,我不理解的地方在这句:
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
可否改成:
sed 's,\($*\)\.o[ :]*,\1.o : ,g' < $@.$$$$ > $@; \
我觉得$@是多余的,后面仔细思考后,进过测试,发现$@是绝对不能少的,且看我的测试程序。
我的依赖关系如如下:
main.o: main.c foo.h
现在我在foo.h里面添加上这样一句话:
#include “barrrrrr.h”
其中barrrrrrr.h文件是不存在的。
在Makefile文件中不加上$@时,编译程序,输出结果:
make: Nothing to be done for 'all'
这显然是不符合预期的,main.c通过foo.h依赖的barrrrr.h,而barrrrrr.h文件又不存在,这应该要报错才对。
查看main.d文件:
main.o: main.c foo.h
原来main.d文件根本就添加对barrrrr.h的依赖!
找到了反例,回过头来想的$@的作用,就很好理解了。
main.d也需要有与main.o相同的依赖。