为 C/C++ 中的项目生成生成文件的依赖项

Posted

技术标签:

【中文标题】为 C/C++ 中的项目生成生成文件的依赖项【英文标题】:generate dependencies for a makefile for a project in C/C++ 【发布时间】:2010-09-23 17:57:56 【问题描述】:

我有一个项目,其生成文件的依赖项已损坏。除了手动检查每个源文件或使用手写的 perl 脚本之外,还有什么最知名的方法可以为我可以在 makefile 中使用的项目生成依赖项列表?

【问题讨论】:

【参考方案1】:

GNU C 预处理器 cpp 有一个选项 -MM,它根据包含模式生成一组合适的依赖项。

【讨论】:

【参考方案2】:

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 $<

注意: $(CXX)/gcc 命令必须是preceded with a hard tab

这将自动为每个已更改的文件生成依赖项,并根据您现有的任何规则编译它们。这使我可以将新文件转储到 src/ 目录中,并自动编译它们、依赖项和所有内容。

【讨论】:

如果文件超过 100 个,不要掉入这个陷阱,因为第一次太慢了。在这种情况下,您应该使用一次调用的东西,而不是每个文件一次。 Makedepend 可能有这个选项。在工作中,我们使用自定义的 perl 脚本。 谢谢,我会记住的。我当前的项目有大约十几个文件,所以它没有很大的开销。此外,初始构建需要 20 多分钟,所以我总是运行它,去喝杯咖啡,然后再运行增量构建。 谢谢,这对我很有帮助。您可以将$(patsubst src/%,obj/%,$(patsubst %.cpp,%.o,$&lt;)) 写成$(patsubst src/%.cpp,obj/%.o,$&lt;) 更简单一点。另外,使用选项-MF $@ 选项而不是使用&gt; $@ 重定向输出不是更有意义吗? g++ 手册页警告您在标准输出上可能有一些不需要的调试输出,但您无法通过 -MF $@ 得到。 @Maarten 好点!我已将您的更改纳入答案。如果您看到任何其他可能有帮助的内容,请随时自行进行编辑。谢谢! 为了避免@SteveHanov 反对,如果依赖项不是最新的,则必须重新编译文件,如果必须重新编译文件,则依赖项可能不是最新的.所以我只是在编译时无条件生成 .d 并且没有特殊规则来重新制作它们。【参考方案3】:

Digital Mars C/C++ 编译器附带一个makedep 工具。

【讨论】:

这适用于哪些平台?【参考方案4】:

现在阅读了this portion in particular,我认为有一个更简单的解决方案,只要你有一个合理的最新版本的 gcc/g++。如果您只是将-MMD 添加到您的CFLAGS,定义一个变量OBJS 代表您的所有目标文件,然后执行:

-include $(OBJS:%.o=%.d)

那么这应该为您提供一个高效且简单的自动依赖构建系统。

【讨论】:

【参考方案5】:

我只是将它添加到 makefile 中,它运行良好:

-include Makefile.deps

Makefile.deps:
    $(CC) $(CFLAGS) -MM *.[ch] > Makefile.deps

【讨论】:

我知道这个答案很旧,但应该是 *.c,而不是 *.[ch] - 无需将每个 *.h 拖入编译器 - 因为它们都应该包含在某些 @ 987654325@ 文件(如果它们被使用)[如果不使用,则依赖关系无关紧要]。 这对每个源的依赖有什么好处吗?似乎您将所有文件的预处理器传递次数增加一倍,但没有真正的好处。 有没有办法重用输出来生成 Makefile 配方或类似的东西?

以上是关于为 C/C++ 中的项目生成生成文件的依赖项的主要内容,如果未能解决你的问题,请参考以下文章

从 MSVC 输出生成 Makefile 依赖项

生成的依赖问题

CMake 有没有办法利用“swig -MM”生成的依赖项?

从stem中的文件名生成makefile目标依赖项

忽略生成的依赖项

MSBuild 复制动态生成的文件作为项目依赖项的一部分