【问题标题】:Makefiles which re-make themselves: makefile not reloaded correctly重新制作自己的 Makefile:makefile 未正确重新加载
【发布时间】:2020-10-17 16:06:25
【问题描述】:

我有一个顶级 makefile,它是由我的自定义构建工具从各种配置文件中自动生成的:我希望 makefile 能够在过期时重新生成。为此,我有以下规则:

<absolute path to makefile>: <list> <of> <configuration> <files>
    @echo "Rebuilding top-level makefile"
    @<invoke my build tool>

我正在使用 GNU Make 4.3,它声称支持这一点,详细说明 here,它声称“在检查了所有 makefile 之后,如果有任何实际更改,make 从一个干净的状态开始并读取所有重新生成makefile。”

我遇到的问题是,虽然这个规则被正确调用(但 不是 隐含,我实际上需要另一个 PHONY 默认目标,它具有 makefile 作为 prerequesite),似乎 make 即使在 makefile 被更改后也不会重新加载它。我注意到,当 make 有配方并且过期时,make 确实会正确地重新加载 included makefile:只有这个顶级 makefile 有问题。

这样做的效果是文件中的其他规则已经过时了,变化只会在后续的make调用中体现出来。

我当前的解决方案是让 makefile 配方返回一个非零退出代码并回显一个警告,要求用户重新运行 make:我尝试使用 ($error _),但这并没有达到预期的效果。

似乎 GNU Make 声称支持这个用例,所以我想我一定是在这里做错了什么?

【问题讨论】:

  • 你是否有机会在 Windows 上运行它?
  • @HolyBlackCat 不,拱门。我设法按照下面的答案修复了它:似乎 GNU Make 无法判断规则中生成文件的绝对路径实际上指向它自己加载的生成文件。

标签: makefile gnu-make


【解决方案1】:

似乎 make(或至少 GNU Make 4.3)无法识别作为规则目标的绝对路径实际上是指它已经自动加载的 makefile:它只是进行简单的文本比较而不是解析路径正确。

将规则更改为:

Makefile: <list> <of> <configuration> <files>
    @echo "Rebuilding top-level makefile"
    @<invoke my build tool>

解决了问题。

我认为这可能应该被视为 GNU Make 中的一个错误,因为它似乎没有记录在案。

【讨论】:

  • 并不是它“处理不了”。就是 make 没有意识到它是同一个文件。 Make 使用简单的文本比较来确定目标是否匹配。如果你运行make -f &lt;absolute path to makefile&gt;,那么make 就会明白你的目标&lt;absolute path to makefile&gt; 是一样的,它会在重建后重新执行。如果您运行make(以便读取默认的Makefile),则make 不会意识到Makefile&lt;absolute path to makefile&gt; 是同一个文件,并且在后者重建后它不会重新执行。
  • @MadScientist make 使用原始文本比较来识别目标的事实正是 为什么 make 无法处理这种情况;我不认为我的说法是错误的?但是,我很惊讶它无法正确统一文件路径,并且我无法在文档中找到任何提及。预期行为的偏差似乎足够大,我认为应该将其视为错误或明确记录。
  • 正如我所说,它CAN 处理绝对路径。您只需在命令行上提供与 makefile 中显示的相同的文件名。因此,“无法处理生成文件的绝对路径”这句话至少具有误导性,我在评论中澄清了真实情况。这种行为(目标的文本比较)适用于所有目标,而不仅仅是重建 makefile 的目标:后者没有什么特别之处。
  • @MadScientist 我不同意这个评估。让我印象深刻的是,sane 行为会让 make 认识到文件指向同一个 makefile 的绝对路径,该文件是通过调用 make 自动选择的,没有 -f 标志;在我看来,make 普遍使用目标的文本比较这一事实并没有使这种行为更加理智,至少在它仍然没有记录的情况下。
  • 我不确定您不同意我评估的哪一部分。据我所知,我所说的一切都是事实。对于当前的行为是对是错,是好是坏,我没有发表任何意见。
猜你喜欢
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多