makefile自动生成依赖关系的2个迷惑
假设我的目录下面有hello.h,hello.cc文件。
root@ubuntu:/home/workspace/Makefile/mf5# g++ -MM hello.cc
hello.o: hello.cc hello.h
自动生成.d文件的规则如下:
include $(src:.cc=.d)
%.d:%.cc
$(cc) -MM $< >$@.$$$$;\
sed 's/$*.o/$*.o $*.d/g' $@.$$$$ > $@;\
rm -f $@.$$$$
第一次执行make的时候,因为.d文件不存在,所以执行了上面%.d:%.cc这条规则,生成hello.d文件,内容为:
hello.o hello.d: hello.cc hello.h
然后make重新读取hello.d这个文件。读取之后,相当于makefile中有了这样一个只有目标和依赖文件而没有命令的规则:
hello.o hello.d: hello.cc hello.h
但是,%.d:%.cc这条规则也可以用来生成hello.d这个目标,那么hello.d如果需要更新的话,make会选择哪条规则,用来更新hello.d呢?
如果使用
hello.o hello.d: hello.cc hello.h
这条规则来更新hello.d,那么没有命令行,make怎么知道如何生成hello.d呢?
------解决方案--------------------%.d:%.cc
$(cc) -MM $< >$@.$$$$;\
sed 's/$*.o/$*.o $*.d/g' $@.$$$$ > $@;\
rm -f $@.$$$$
.d的更新用上面的这个命令
.d文件只指明依赖关系而已
可以将include的内容展开看
------解决方案--------------------个人理解include $(src:.cc=.d)只是引入一条规则,仅仅是在此处展开该依赖关系,并没有在此处使用;
就好比C中,头文件定义并实现函数fun(),别的文件include头文件仅仅是展开代码,其他地方调用fun()函数时才会执行fun();
呃,我是这样理解的
------解决方案--------------------makefile中有目标和依赖文件而没有命令的规则:
hello.o hello.d: hello.cc hello.h
“也就是.d文件被include之后,make会试图更新.d文件。”,只有规则没有命令make不知道怎么更新啊,是gcc、g++还是其他命令、带什么参数等将.cc文件转化成.d文件,make命令都不知道,所以在%.d:%.cc这里才更新.d文件