使用 Makefile、源代码生成器并使用 gcc 生成依赖项

Posted

技术标签:

【中文标题】使用 Makefile、源代码生成器并使用 gcc 生成依赖项【英文标题】:Working with Makefile, source generators and generating dependencies with gcc 【发布时间】:2014-09-25 16:28:07 【问题描述】:

在我的项目中:

main.cpp template.sth 更多

对于每个.cpp 文件,我正在生成.o 文件。 多亏了这一点,我可以为所有 .o 目标编写简单的规则(为了更清晰,简化了一点伪代码版本):

OBJS = #list of all .o files needed

%.o: %.cpp
    g++ -MM -MF %.d -MP -MT %.o %.cpp
    g++ -c -o %.o %.cpp

然后我包含所有现有的.d 文件,因此在每一代之后我都会刷新依赖项。

除非我有template.sth,否则它会起作用。该文件包含一些用于生成h 文件和cpp 文件的模板。

当一个文件,即main.cpp 包含从template.sth 生成的文件时(比如说gen.h):

    生成.d 文件的指令不起作用,因为缺少gen.hfatal error: gen.h: No such file or directoryinclude "gen.h" 即使这些说明可行,我的“工作流程”也有问题。到目前为止,我可以为下一次制作生成.d 文件。它起作用了,因为添加新的依赖项需要更改当前的依赖项之一。因此,在添加一个.o 后正在重建并生成新的.d。现在我需要在制作.o 之前检测到我需要从template.sth 生成gen.h

有什么办法可以自动完成吗?问题 1. 如果有某种方法可以告诉 g++ 如果缺少某些 .h 文件,则可以将其添加到依赖项中。 解决问题 1. 多次执行 make(我认为两次就足够了)以构建项目结束(第一个 make 会生成依赖文件,然后第二个 make 看到 main.cpp 依赖于 gen.h,@987654350 @ 缺失,并且有说明如何创建 gen.h,因此它将在构建 main.o 之前创建 gen.h

如果不能以某种方式自动完成,如何解决?我可以在Makefile 指令中编写将在任何其他文件之前构建所有生成的文件,还是我需要手动将此生成的文件添加为所有.o 指令中的依赖项?

更新:

经过一些更改,-MG 标志 g++ 甚至为 gen.h 生成正确的文件。我现在可以使用两个make 命令构建我的项目。 第一个将创建正确的.d 文件并中断,因为缺少gen.h。 第二个将准备好.d文件,因此它会在构建main.o之前生成gen.h,因此构建main.o会成功。

有没有办法在生成.o之前生成.d文件然后使用它?

【问题讨论】:

【参考方案1】:

需要为生成的文件添加依赖:

gen.h: template.sth
        ...command to create gen.h from template.sth

如果您有很多生成的文件,您可能需要一种自动创建这些依赖项的方法,这取决于您生成它们的方式。

此外,您希望独立于 .o 文件生成 .d 文件,并在生成它们时使用 -MG 标志以忽略丢失的文件:

%.d: %.cpp
        g++ -MM -MF $@ -MP -MG $<

-include $(OBJS:.o=.d)

这样,第一次运行 make 时,它​​会生成带有依赖项的 .d 文件,然后重新读取它们并重新计算所有依赖项,然后再尝试构建其他任何东西。

【讨论】:

我有这个。问题是在 Makefile 中 main.o 和 gen.h 之间没有依赖关系。 @Ari 您正在寻找一种自动方式将 gen.h 添加到 main.o 的依赖项列表中是否正确?请注意,目标文件依赖于它们包含的所有头文件,因此 main.o → gen.h 之类的依赖项应该在您的 Makefile 中,无论是否生成了 gen.h @MichaelGrünewald 是的,就像我添加未生成的依赖项一样。 必须显式添加对生成的头文件的依赖。无法自动检测生成的头文件(与所有派生对象一样)。只能自动检测源文件。

以上是关于使用 Makefile、源代码生成器并使用 gcc 生成依赖项的主要内容,如果未能解决你的问题,请参考以下文章

Makefile学习7————自动生成依赖关系 三颗星

从 MSVC 输出生成 Makefile 依赖项

从MSVC输出生成Makefile依赖项

Ubuntu下makefile及gcc生成静态库动态库的简单使用举例

自动编译当前目录下所有文件的Makefile

configure生成makefile的配置项说明