我正在阅读一个Makefile,我找到了一种自动生成先决条件的方法,它与this tutorial不同。该方法如下:
DEPFILES = $(SRCFILES:src/%.cpp=obj/%.d)
-include $(DEPFILES)
obj/%.o: src/%.cpp | obj
@echo compiling $(@F) ...
@$(CXX) -O3 -ggdb $(CXXFLAGS) -c -o $(@) -MMD -MP $(<)
obj:
@mkdir $@
我可以弄清楚gcc如何生成.d文件,当我第一次执行make
命令时,-include $(DEPFILES)
将失败并且obj/%.o
目标将被调用并生成.d文件。但我的问题是:当我修改一些源文件并再次执行make
时,会发生什么?我认为-include $(DEPFILES)
将成功并且.d文件包含在makefile中,因此.d文件中的obj/%.o
目标包含在makefile中,但实际上我已经定义了obj/%.o
目标在原始makefile中,是冲突吗?
我做了一些实验,发现原始makefile中的obj/%.o
目标将被调用(因为执行echo
命令),并且必要时会更新.d文件。但为什么呢?我们需要.d文件中的目标来了解依赖项以及为什么不调用它?
答案 0 :(得分:2)
当你设置一个Makefile时,一行只是一个目标和依赖,而后面没有任何指令只是一个额外的依赖。所以,作为一个例子:
a.o: a.cpp
g++ -o $@ -c $+
a.o: a.h b.h
第一行说要构建a.o
,它取决于a.cpp
,然后说明如何构建它。第二个a.o
只会在a.h
和b.h
上添加其他依赖项。这基本上就是上面的机制所做的,因为它定义了很多额外的依赖行,但是没有添加任何指令。