Makefile:如何检测 makefile 本身的变化?

Makefile: how to detect changes within the makefile itself?

我知道使用递归 makefile 的想法。是否会仅根据对后续 makefile 本身的任何更改来更新如下所示的后续 makefile?

例如:

#parent makefile. no changes here. 
subsystem:
    cd subdir && $(MAKE)

如果 subdir 中的 makefile 被更改使得以下内容不成立(例如,仅更改了 gcc 标志),那么目标文件是否会更新?

The recompilation must be done if the source file, or any of the header files named as dependencies, is more recent than the object file, or if the object file does not exist.

如所写,甚至 运行 规则的唯一原因是因为 subsystemsubdir 不匹配。

如果要在该目录中创建 subsystem 文件或目录,则该规则将停止运行。

如果添加 .PHONY: subsystem1,问题将得到解决,并且该规则将 始终 运行 在命令行中列出时(即 make subsystem)。 (如评论中所示 .PHONY 是 GNU Make 扩展。链接部分后面的部分讨论了可移植的替代方案。尽管值得注意的是它们并不完全相同,因为 .PHONY 有一些额外的好处以及一些额外的限制。)

在这两种情况下,subsystem 目标都不会关注任何内容的修改日期(因为它没有列出先决条件)。

要使目标依赖于对 makefile 的更改,您需要像其他任何东西一样将 makefile 列为先决条件(即 subsystem: subdir/Makefile)。将其列为 .PHONY 可能更正确,也更符合您的要求。

不,make 本身没有任何内容可以跟踪非先决条件。所以标志changes/etc。不要触发重建。然而,有一些方法可以使 make 工作(它们涉及将使用的标志存储在文件中,这些文件本身是使用这些标志的目标的先决条件等)。 SO 上有关于这样做的问题和答案(不过我还没有准备好它们)。

但是其他工具会自动处理标志更改。我相信 Electric Cloud's tools do this. I believe CMake 也是如此。可能还有其他人。

您可以将 makefile 包含为依赖项,与任何其他文件一样:

mytarget.o: mytarget.c Makefile

无论是否有任何更改,都会执行递归生成文件。这正是 Paul Miller 在近 20 年前的 Recursive make considered harmful 论文中指出的反对意见之一。

也就是说,makefile 就像任何其他依赖项一样,可以添加到生产规则以在 makefile 被更改时触发该规则。