【问题标题】:Automatically discovering C dependencies自动发现 C 依赖项
【发布时间】:2020-02-21 09:31:56
【问题描述】:

我需要为我当前的项目编写文档,列出所有 .c 文件,并为每个项目列出该文件直接或间接包含的每个 .h 文件。

这是一个大型项目,虽然我们有 Makefiles,理论上有这些信息,但这些 Makefiles 有时是不正确的(我们从另一家公司继承了这个项目)。我们经常需要make clean ; make 才能让我们的更改真正反映在重新编译中,所以我不想依赖这些 Makefile。

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

#define my_include "some_file.h"
#include my_include

因此该工具不需要完美无缺。在包含路径中搜索 .c 和 .h 文件以进行常规包含的任何内容都足够了。

【问题讨论】:

    标签: c include dependencies


    【解决方案1】:

    我在 Makefile 中所做的是

    SRCS=$(wildcard *.c)
    
    depend: $(SRCS)
        gcc -M $(CFLAGS) $(SRCS) >depend
    
    include depend
    

    这意味着如果任何源文件被更新,depend 规则将运行,并使用 gcc -M 来更新名为depend 的文件。然后将其包含在 makefile 中,以提供所有源文件的依赖规则。

    Make 将在包含文件之前检查文件是否是最新的,因此,只要您运行 make,此依赖规则就会在必要时运行,而无需执行“make depend”。

    这将在任何文件发生更改时运行。我从来没有发现这是一个问题,但是如果目录中有大量文件,您可能会发现花费的时间太长,在这种情况下,您可以尝试为每个源文件设置一个依赖文件,如下所示:

    SRCS=$(wildcard *.c)
    DEPS=$(SRCS:.c=.dep)
    
    %.dep : %.c
        gcc -M $(CFLAGS) $< >$@
    
    include $(DEPS)
    

    请注意,您可以使用 -MM 代替 -M 来不包含系统标头。

    【讨论】:

    • 您可以更改标题以包含额外的标题,从而更改所有源文件的依赖关系,但您的依赖关系列表不会得到更新。让它完全正确可能是相当复杂的 IIRC,但一个好的开始是将所有你自己的头文件包含在依赖的依赖项中。
    • 哦,为了性能注意,如果任何文件发生更改,这将重新处理所有文件。因此,您可能希望拥有多个依赖文件(甚至每个源文件一个)。最后,请注意,您通常可以使用 -MM,它会跳过对系统标头的依赖,因为您不会更改它们。
    • 其实我撒谎了——我自己总是用-MM :)
    • 我不知道你可以包含多个文件,但我刚刚检查过,你可以,所以是的,如果你发现性能问题,每个源文件一个依赖文件是一个不错的选择我这样做的方式 - 就我个人而言,我几乎没有注意到它在做任何事情。
    • 如何防止 .dep 文件在清理后重建?
    【解决方案2】:

    "gcc -M file.c" 满足您的需求。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        使用 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
          ...
        

        【讨论】:

        • 不错!我实际上查看了 SCons API,因为我认为我必须弄乱它的内部结构才能让它做到这一点。以后我会记住这个命令行开关。
        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-29
          • 1970-01-01
          • 2011-09-28
          • 2012-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多