我有一个项目,其中Makefile的依赖关系出现了问题。 除了手动检查每个源文件或使用手写的perl脚本之外,是否有任何已知的最佳方法来生成可用于Makefile的项目依赖项列表?
我有一个项目,其中Makefile的依赖关系出现了问题。 除了手动检查每个源文件或使用手写的perl脚本之外,是否有任何已知的最佳方法来生成可用于Makefile的项目依赖项列表?
GNU make的文档提供了一个很好的解决方案。
当然。 g++ -MM <your file>
会生成一个GMake兼容的依赖列表。我使用类似这样的东西:
# Add .d to Make's recognized suffixes.
SUFFIXES += .d
#We don't need to clean up when we're making these targets
NODEPS:=clean tags svn
#Find all the C++ files in the src/ directory
SOURCES:=$(shell find src/ -name "*.cpp")
#These are the dependency files, which make will clean up after it creates them
DEPFILES:=$(patsubst %.cpp,%.d,$(SOURCES))
#Don't create dependencies when we're cleaning, for instance
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
#Chances are, these files don't exist. GMake will create them and
#clean up automatically afterwards
-include $(DEPFILES)
endif
#This is the rule for creating the dependency files
src/%.d: src/%.cpp
$(CXX) $(CXXFLAGS) -MM -MT '$(patsubst src/%.cpp,obj/%.o,$<)' $< -MF $@
#This rule does the compilation
obj/%.o: src/%.cpp src/%.d src/%.h
@$(MKDIR) $(dir $@)
$(CXX) $(CXXFLAGS) -o $@ -c $<
src/
目录中,自动编译它们,包括依赖关系。现在我已经阅读了特别的这一部分,我认为有一个更简单的解决方案,只要你有一个相当新的版本的gcc/g++。如果你只是将-MMD
添加到你的CFLAGS
中,定义一个表示所有对象文件的变量OBJS
,然后执行:
-include $(OBJS:%.o=%.d)
那么这应该可以帮助您获得高效且简单的自动依赖构建系统。
我只是在 makefile 中添加了这个,它很好地运行:
-include Makefile.deps
Makefile.deps:
$(CC) $(CFLAGS) -MM *.c > $@
*.c
而不是 *.[ch]
- 没有必要将每个 *.h
文件都引入编译器 - 因为如果它们被使用,它们都应该由一些 .c
文件包含 [如果它们没有被使用,则依赖关系无关紧要]。 - Mats Petersson
$(patsubst src/%,obj/%,$(patsubst %.cpp,%.o,$<))
简化为$(patsubst src/%.cpp,obj/%.o,$<)
。另外,使用选项-MF $@
而不是重定向输出到> $@
会更有意义吧?g++手册警告可能会在stdout上产生一些不需要的调试输出,但使用-MF $@
则不会出现这种情况。 - Maarten