【问题标题】:How to collect all dependencies of a large Makefile project?如何收集大型 Makefile 项目的所有依赖项?
【发布时间】:2014-07-07 11:47:14
【问题描述】:

在一个大型 C 项目中,我在不同的子目录中有一个顶级 Makefile 和许多子 Makefile。我需要收集编译的所有依赖项。为此,我将 -MMD 添加到 CFLAGS 并获得一堆 .d 依赖文件。

这些 .d 文件分散在子目录中。此外,依赖项有时写为绝对路径,有时写为与编译目录相关的路径,有时包含符号链接。我编写了一个脚本,它可以查找所有 .d 文件、遍历它们的目录并解析所有找到的路径。这是可行的,但是对于成千上万的依赖文件,这个依赖集合的持续时间与编译时间差不多! (等待时间太长了:))

有没有更快的方法在一个文件中获取所有依赖项?如果重要的话,这是 ANSI C、GCC 和 Linux。提前致谢。

【问题讨论】:

    标签: c gcc makefile


    【解决方案1】:

    您可以使用-MM 代替-MMD,它将依赖项发送到标准输出。

    然后,您可以使用

    将所有输出收集到顶级目录中的某个依赖文件中
    gcc -MM ... file.c >>$(top)/all.d
    

    如果后处理是将输出收集到一个文件中的唯一原因,您可以使用管道过滤输出

    gcc -MM ... file.c | sh filter.sh >file.d
    

    并将依赖文件分开。

    如果某些本地包含文件 (defs.h) 或主要来源的路径很重要,您可以通过提供适当的 -I 选项来强制 gcc 包含路径,例如

    gcc -MM -I$(top)/path/to ... $(top)/path/to/file.c >>$(top)/all.d
    

    gcc -MM -I$(top)/path/to ... $(top)/path/to/file.c | sh filter.sh >file.d
    

    代替

    file.o: file.c defs.h
    

    gcc 会发出

    file.o: /absolute/path/to/file.c /absolute/path/to/defs.h
    

    当然,这也适用于相对路径。

    【讨论】:

    • 但是我有许多具有相同文件名的依赖项,例如dir1/defs.hdir2/defs.h,它们通过相对路径(使用#include "defs.h")从相应目录中包含在源文件中。 gcc -MM ... file.c >>$(top)/all.d 将只输出defs.h,我不知道使用了defs.h 中的哪一个。
    • 第二种方案怎么样?
    • 第二种选择与我现在所做的没有太大区别:除了标准输入之外,过滤器还必须接收正在执行的 gcc 的路径。现在我的脚本从find 的输出中接收.d 文件的路径。我想唯一可以“更快”地做到这一点的是 GCC 的一个选项,它将为依赖文件生成 resolved absolute 路径。似乎不存在这样的选择......
    • 另请参阅问题stackoverflow.com/q/18136918/1741542 以使用 make 确定当前目录。
    • 谢谢你的回答,但我不能让它工作。如果我的 test.c 文件只包含一行 #include defs.h,则 gcc -I$PWD -MM test.c 输出 test.o: test. c defs.h。我没有得到依赖的绝对路径。
    【解决方案2】:

    您可以在第一次编译运行时创建依赖文件。

    在第一次运行期间,对象还不存在,因此无论如何都会调用编译器。首先创建空的依赖文件,然后在编译时更新它们。

    应该可以扩展minimal Makefile for a single-directory C++ project 以使用子目录。

    【讨论】:

      猜你喜欢
      • 2010-09-16
      • 2016-08-14
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 2012-02-08
      • 2018-12-27
      • 2021-01-04
      相关资源
      最近更新 更多