EDITED
我正在尝试重新编译源文件,而不必为makefile中的每个CPP指定头文件。
我到了:
#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)
#This is the makefile.
CORE_COMPONENT_OBJECTS = \
obj/CoreObj1.o \
obj/CoreObj2.o \
# Objects
obj/%.o: %.cpp obj/%.d
@mkdir -p obj
$(CXX) $(CXX_CFLAGS) -c $*.cpp -o $@
# Dependencies
obj/%.d: %.cpp
@mkdir -p obj
$(CXX) $(CXX_CFLAGS) -MM -MF $@ $<
DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
但修改头文件不会触发源文件,包括重新编译它。
注意:实际上,如果我的.o,.d和.cpp位于同一个文件夹中,它就可以正常工作。但是如果我的.d和.o位于obj /文件夹中,则不会触发重新编译。
答案 0 :(得分:4)
人们经常会有依赖关系生成的规则,但实际上并没有必要。
第一次构建项目时,不需要依赖项,因为它无论如何都会构建所有源代码。只有后续构建才需要先前构建的依赖项来检测需要重建的内容。
因此,依赖关系实际上是编译的副产品。您的规则应如下所示:
#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)
#This is the makefile.
CORE_COMPONENT_OBJECTS = \
obj/CoreObj1.o \
obj/CoreObj2.o \
# Objects
obj/%.o: %.cpp
@mkdir -p obj
$(CXX) $(CXX_CFLAGS) -c -o $@ -MD -MP -MF ${@:.o=.d} $<
DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
作为旁注,mkdir -p
不是平行的友好。例如,当两个或多个进程在/a/b/c/
不存在时竞争创建/a/b/cc/
和/a/b/
时,一个mkdir
进程可能会因EEXIST
尝试失败而失败创建/a/b/
。
答案 1 :(得分:0)
您没有依赖项文件作为编译规则的先决条件。应该是这样的:
#This is the rule for creating the dependency files
src/%.d: src/%.cpp
$(CXX) $(CXX_CFLAGS) -MM -MF $(patsubst obj/%.o,obj/%.d,$@) -o $@ $<
obj/%.o: %.cpp %.d
$(CXX) $(CXXFLAGS) -o $@ -c $<
-include $(SRC:%.cpp=%.d)
最后一个字符串会增加对标题的依赖。
修改
我看到你有
-include $(DEPS)
但请检查 $(警告DEPS = $(DEPS))是否确实包含现有文件,否则请默默忽略这些文件。
答案 2 :(得分:-2)
最好使用SCons/CMake/bjam
解决“标头依赖问题”,而不是使用make