2014-05-19 38 views
4

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

这些.d文件分散在子目录中。此外,依赖关系有时被编写为绝对路径,有时作为与编译目录相关的路径,有时包含符号链接。我编写了一个脚本,用于查找所有.d文件,遍历其目录,并解析所有找到的路径。这有效,但有数以万计的依赖关系文件,这个依赖关系集合持续大约与编译相同的时间! (这是等待太久:))

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

回答

1

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

然后,您可以收集所有的输出到顶层目录中的一些依赖文件,

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 

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

+0

但是我有许多相同的文件名,比如'dir1/defs.h'和'dir2/defs.h',它们由相应的目录中的源文件包含相对路径(使用'#include“defs.h “')。 'gcc -MM ... file.c >> $(top)/ all.d'只输出'defs.h',我不知道使用了哪个'defs.h'。 – user3608247

+0

第二种方案如何? –

+0

第二种选择与我现在所做的没有多大区别:过滤器必须接收除stdin之外正在执行的** gcc **的路径。现在我的脚本从** find **的输出接收** .d **文件的路径。 我想唯一可以做到的“更快”是GCC的一个选项,它可以为依赖文件生成**解析绝对**路径。没有这样的选项似乎存在... – user3608247

0

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

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

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