跟踪#include依赖项的工具

193
任何好的建议吗?输入将是一个头文件的名称,输出应该是直接或间接包含它的所有文件的列表(最好是树形结构)。

5
这段话的意思是:这不是关于GCC中漂亮显示“favorite”选项,但MSVS不能。所以我们(我)正在寻找任何工具。我的翻译:此处并非指GCC中美观展示“喜爱”的选项,但在MSVS中却无法实现。因此,我们(我)正在寻找任何相关工具。 - Fantastory
95
为什么我总是发现“离题”的问题非常有帮助? - jfritz42
7
@jfritz42 :这应该获得“年度评论”奖!当有如此多的话题和用户时,一个版主如何将一个问题标记为“离题”? - Totoro
3
我想指出,有很多处理#include依赖关系的工具,例如cpp-dependenciesiwyudep-matrix,后者是一个用Python编写的相当简单的工具。 - nonsensickle
3
数字很清楚:123个投票和62个收藏。很多人这样看待。Stack Overflow的标准很奇怪。我也怀疑在SuperUser上这样的问题是否会得到同样好的答案。 - Andreas
显示剩余5条评论
10个回答

172
如果您可以访问GCC/G++,那么-M选项将输出依赖关系列表。它不执行其他工具所做的任何额外操作,但由于它来自编译器,因此不会有机会从“错误”的位置获取文件。

74
“-H”甚至还提供了一棵树! - SamB
35
-MM 跳过系统头文件。 - TheJosh
3
使用-o选项,编译器会将输出写入文件而非标准输出。 - Hi-Angel
2
@SamB 只有在没有错误的情况下,它才有效,并且会将内容打印到stderr而不是stdout。否则,该选项更为通用。 - user877329
clang也支持完全相同的选项。请查看clang命令行参数页面 - RAM
显示剩余2条评论

96

感谢KeithB。 我查看了cl.exe(VS2008)的文档,并找到了/showIncludes标志。从IDE中,可以在任何CPP文件的属性页面中设置此标志。

屏幕截图


2
这在解决一些非常难的编译错误/警告方面非常有用。非常感谢! - Ashwin Nanjappa
当尝试优化预编译头文件时,这也非常方便! - fmuecke
在使用VS时,我认为这是解决我的问题最快的方法~ :-) - yaobin
这似乎不起作用,如果某个头文件包含了一个标准的c头文件,例如 math.h - abergmeier

30

如果你需要一种重量级的解决方案,可以尝试查看doxygen。它会扫描你的代码库,并生成一个有效的网站来记录你的代码,其中包括依赖关系树等内容。

如果你希望将此工具的输出连接到其他进程,则可能不适用(虽然doxygen可以输出到其他格式,但我对该功能不太熟悉)。但如果你只是想查看依赖关系,则这个工具非常适合。


那怎么确定是“不必要”的呢?我有一个叫做“foo.cpp”的文件,它包含(直接或间接地)“bar.h”……如果移除“bar.h”,是否会对“foo.cpp”的编译输出造成任何差异?如果答案是否定的,那么这就是一个不必要的包含。这很困难……“foo.h”可能会定义一些在完全不同的.h文件中用#if表示的东西…… - David V. Corbin

20

我曾经尝试使用一个叫做cinclude2dot的工具。在我来这里工作时,它对于理解一个相当大的代码库非常有用。我实际上考虑将其最终整合到我们的日常构建中。


2
这个工具运行得非常好。我在使用g++的-M和doxygen时遇到了麻烦。 - sleeparrow
我编写了一个Python脚本来读取cinclude2dot的输出,并将所有依赖关系存储在一个映射中,然后进行深度优先遍历,最终输出源代码的森林。如果森林中没有任何.cc/.c/.cxx文件(只有其中的.h文件),则可能是多余的。 - KRoy

14

好消息: Redhat源码导航(也可在Windows上运行)。当然,编译器开关(前面提到过)具有更强的解析能力,我不确定这个工具如何处理MFC、Qt及其特殊关键字。

Redhat源码导航


13

首先,cinclude2dot.pl是一个perl脚本,它分析C/C++代码并生成一个包含依赖关系的图形文件作为输入到graphviz中。

http://www.flourish.org/cinclude2dot/

如果您不想使用这种类型的手动工具,那么在我看来,毫无疑问,最好的选择是来自ProFactor的"IncludeManager"工具。

http://www.profactor.co.uk/includemanager.php

它有一个免费试用版,非常棒。它是Visual Studio的插件,完全集成,因此在此处双击某个东西会将您带到包含它的位置。

工具提示鼠标悬停时会提供您想要的所有信息,并允许您向下/向上钻取,删除您不关心的整个子树,查看除图形以外的表示形式,循环浏览与此和那个匹配的列表,非常出色。

如果您快速进行,可以在试用期内重构大型项目的#include结构。即使如此,它的成本也不高,大约每个许可证35美元。

对于它所做的事情,它几乎是完美的。不仅包含依赖图,还包括共享文件的跨项目依赖关系、对构建时间的影响、网格中的详细属性,非常出色。


我已经成功地在我的C项目中使用了IncludeManager。我正在使用Visual Studio 2013。 - smwikipedia
有点可疑。 - sdd
不再使用那个链接了... - David V. Corbin

7

KeithB的回答 的基础上,以下是GNUmake语法,自动完成1)生成依赖文件,2)保持它们的最新状态,3)在您的makefile中使用它们:

.dep:
    mkdir $@
.dep/%.dep: %.c .dep
    (echo $@ \\; $(CC) $(IFLAGS) -MM $<) > $@ || (rm $@; false)
.dep/%.dep: %.cpp .dep
    (echo $@ \\; $(CXX) $(IFLAGS) -MM $<) > $@ || (rm $@; false)
DEPEND := $(patsubst %.dep,.dep/%.dep,$(OBJ:.o=.dep))
-include $(DEPEND)

确保将这些缩进更改为硬制表符。


4

Understand for C++可以帮助您:它构建了一个数据库,您可以从Perl访问。


Understand是商业软件,但在我看来非常棒。你可以免费试用它。 - skelliam

2

cscope (http://cscope.sourceforge.net/) 可以在一个独立的 xterm 中运行,也可以在你最喜欢的编辑器中使用——它拥有出色的 emacs 和 vi/vim 支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接