2008-10-15 82 views
11

我需要为我当前的项目编写文档,其中列出了所有的.c文件,并且每个列出了该文件直接或间接包含的每个.h文件。自动发现C依赖关系

这是一个大型项目,虽然我们有理论上有这种信息的Makefiles,但这些Makefiles有时是不正确的(我们从另一家公司继承了此项目)。我们经常必须为我们的更改做一个make clean ; make实际上反映在重新编译中,所以我不想依赖这些Makefiles。

那么有没有一种工具可以让我们给它一个.c文件的名称和一个包含路径,并让它告诉我们.c文件直接或间接包含的所有.h文件?我们没有任何奇怪的东西像

#define my_include "some_file.h" 
#include my_include 

所以这个工具不需要是完美的。任何搜索包含常规包含路径中的.c和.h文件都足够好。

回答

14

我在Makefile中做的是

SRCS=$(wildcard *.c) 

depend: $(SRCS) 
    gcc -M $(CFLAGS) $(SRCS) >depend 

include depend 

这意味着,如果任意一个源文件被更新时,依靠规则运行,并使用gcc -M更新名为依赖于文件。这包含在makefile中,为所有源文件提供相关性规则。

Make会在包含它之前检查文件是否是最新的,因此,如果需要运行make,而不需要执行“make depend”,则此依赖规则将运行。

这将在任何时候任何文件发生变化时运行。我从未发现过这个问题,但是如果目录中有大量文件,则可能会花费太长时间,在这种情况下,您可以尝试每个源文件都有一个相关文件,如下所示:

SRCS=$(wildcard *.c) 
DEPS=$(SRCS:.c=.dep) 

%.dep : %.c 
    gcc -M $(CFLAGS) $< >[email protected] 

include $(DEPS) 

请注意,您可以使用-MM而不是-M不包含系统标题。

+0

你可以改变一个头,包括一个额外的头,从而改变所有的源文件的依赖关系,但你所依赖的列表将不会被更新。完全正确地完成它可能非常费力IIRC,但一个好的开始是将所有自己的头文件包含在依赖关系中。 – 2008-10-27 14:42:37

+2

哦,为了提高性能,请注意,如果有任何文件发生更改,则会重新处理所有文件。所以你可能想要有多个依赖文件(甚至每个源文件可能有一个)。最后,请注意,您通常可以使用-MM,这会跳过对系统标题的依赖关系,因为您不会更改它们。 – 2008-10-27 14:49:08

+0

其实我说谎 - 我总是用-MM我自己:) – 2008-10-28 17:11:47

5

“gcc -M file.c”可以满足您的需求。

1

在MSVC(至少2005年和2008年,可能还有其他版本,但不是VC6),您可以让编译器告诉您编译期间包含的所有文件。输出结果非常详细,但完整且相当容易用人眼分析。

在项目设置中,转到C/C++>高级选项卡,然后切换“显示包含”,然后从头开始重建项目。

4

gcc -M的替代方案是fastdep。 Fastdep的作者报告fastdep比gcc -M快十倍。如果项目需要一段时间才能构建,fastdep可能值得一看。

2

使用SCons的

$ scons --tree=all 
scons: Reading SConscript files ... 

scons: done reading SConscript files. 
scons: Building targets ... 
scons: `.' is up to date. 
+-. 
    +-SConstruct 
    +-app 
    | +-test.o 
    | | +-test.c 
    | | +-/include/PCI_1149_1.h 
    | | +-/include/Pci.h 
    | | +-/usr/bin/gcc 
    | +-/usr/bin/gcc 
    | +-/lib/libpci1149_64.a 
    ...