【问题标题】:How to make Make generates headers before compiling?如何让Make在编译前生成头文件?
【发布时间】:2020-08-07 00:02:44
【问题描述】:

我很难编译我的 CPP 文件,因为缺少头文件。我知道它丢失了,因为我想生成它。怎么样?

这是我目前所拥有的。问题是:当在多个 CPP 文件中使用“the_header.hpp”时,make 的递归调用效率不高(也不令人满意),因为“the_header.hpp”中包含的头文件似乎由于 并行性而被重建了几次强>。

CPP 文件 %.cpp :

#include "the_header.hpp"

// ...

我的 Makefile :

#
include *.g *.d

# *.g like generator
%.g: %.cpp
    g++ -MM -MF $@ -MP -MG -MT $@ $<
    make $@

#
%.d: %.g ;

#
%.o : %.cpp %.d
    // g++ with auto-dependencies generation

# the_header.hpp matches
%.hpp : %.lcm
    // Generate it

并且只是为了清除我的意图:当我编译 CPP 文件时,我会生成一个 %.g 文件,该文件的目标将为其自身添加更多先决条件。递归调用最终会将“the_header.hpp”视为先决条件(而不是最新的),生成它并重新生成 %.g。递归调用将看到“the_header.hpp”是最新的,无事可做,递归结束。编译过程。

此外,“the_header.hpp”是 LCM 生成的文件,其中 lcmgen 来自 %.lcm 文件。

在这样做之前,我刚刚(并行性很好,但都不令人满意):

#
%.o : %.cpp %.d $(patsubst %.lcm,%.hpp,$(wildcard *.lcm)

不知道实际使用了哪些 lcm 文件。另外,我混合了 C 和 C++ 项目,这可能会导致:

# lcmgen can be used with both C++ or C...
%.o : %.cpp %.d $(patsubst %.lcm,%.hpp,$(wildcard *.lcm) $(patsubst %.lcm,%.h,$(wildcard *.lcm)

我希望你会觉得它很有趣!

【问题讨论】:

  • “并行性很好,但都不令人满意)” 为什么不令人满意?
  • make.mad-scientist.net/papers/… 你可能会感兴趣。
  • @Jarod42 都不令人满意,因为我把所有可能性都放在了我需要的地方
  • @Jarod42 另外,我应用了make.mad-scientist.net/papers/… 中的内容:)
  • 应该是$(wildcard *.g *.d)。此外,当您刚刚在上一行中创建它时,您为什么要在 %.g : %.cppmake $@?另外:真的总是包含您收到的错误消息,只是为了更清楚我们在说什么。

标签: c++ c gcc makefile


【解决方案1】:

没有办法使用任何形式的现代自动生成先决条件和构造的标题。当标头不存在时,任何基于编译器的先决条件生成器都会失败。

对于生成的标头,除了显式声明先决条件之外,您几乎没有任何合理的选择。不过,您没有理由需要在模式规则中这样做,这只会增加很多复杂性。

假设您有源文件foo.cbar.cbaz.c,前两个依赖于生成的标头,但最后一个没有。只需将这些行添加到您的 makefile 中:

foo.o bar.o : the_header.hpp

就是这样。无需搞乱模式规则。

【讨论】:

  • 我不清楚我的选择。我了解您希望保持 Makefile 的“标准”。如果我仍然想为目标自动生成先决条件 the_header.hpp,你会建议在执行 Makefile 之前在外部执行它,假设我不能(不想)显式编写先决条件(并且这样做是在我原来问题的范围)。
  • 抱歉,我不太明白您所说的保持 Makefile“标准” 是什么意思。无论如何,并行性多次重建事物等问题的答案是添加先决条件。这是 make 提供的唯一解决方案。如果您出于某种奇怪的原因不想这样做,那么您唯一的选择是使用 make 之外的解决方案。一个这样的解决方案是,是的,拥有一个总是首先构建标题然后构建其余部分的包装脚本。这听起来很奇怪,但我显然不熟悉你的环境,所以我知道什么?
  • 我完全同意你的看法!我需要先决条件,我只是在寻找一种编写它们的方法,但 make 似乎不是答案,这很好:) gcc 用于先决条件确定,我想我需要类似的东西
  • 我不明白:我通过添加明确的依赖行(例如我的答案中的最后一个示例)来展示您需要做什么来编写它们。
  • 在我上面的 cmets 中,我写道“此外,当您刚刚在上一个 [recipe-] 行中创建 $@ 时,为什么要在 %.g : %.cpp 中创建它?....I不要认为在目标的配方中再次对这个目标递归调用 make 是没有意义的。”。我会犯错还是这样做真的毫无意义?据我所知,我认为是这样,但我有一种感觉,不知怎的,我忽略了一个场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-17
相关资源
最近更新 更多