jom/nmake 创建两个文件的规则

jom/nmake rule that creats tow files

我正在将 Makefile 从 omake.exe(从 ClearCase)迁移到 jom.exe/nmake.exe.

一个简化的 Makefile 示例:

all: bin1 bin2

rule1 rule2: rule3
    @echo creating rule1 and rule2
    @touch rule1 rule2

rule3:
    @echo creating rule3
    @touch rule3

bin1: rule1
    @echo creating bin1
    @touch bin1

bin2: rule2
    @echo creating bin2
    @touch bin2

touch 只是创建一个文件,或者如果它已经存在则更新时间戳。

jom/namke 的输出是:

creating rule3
creating rule1 and rule2
creating rule1 and rule2
creating bin1
creating bin2

创建规则 1 和规则 2 执行了两次。

使用 omake 时,规则只执行一次,意思是在一个命令中创建文件 rule1 和 rule2(这里使用 touch)。

同时创建rule1和rule2的命令只调用一次,需要修改什么?

谢谢 泰迪

我对 omake 或 nmake 都一无所知。但我可以为您提供有关标准 (POSIX) make 的信息,并且在 make 的这些实例遵守标准的范围内,它可能会有用。

在标准 make 中,此规则:

rule1 rule2: rule3
         @echo creating rule1 and rule2
         @touch rule1 rule2

绝不意味着“一次调用配方构建两个目标”。它被解释为与您编写的完全相同:

rule1: rule3
         @echo creating rule1 and rule2
         @touch rule1 rule2
rule2: rule3
         @echo creating rule1 and rule2
         @touch rule1 rule2

因此,从某种意义上说,您在 nmake 中看到的行为是可以预料的。除了,它永远不会像 POSIX make 那样工作,因为 POSIX make 总是一次运行一个规则。所以,首先它会尝试构建 rule1,而这实际上同时构建了 rule1rule2。因此当 make 调查它是否需要构建 rule2 时,它发现它已经是最新的并且不做任何事情。

因此即使 make 将此规则解释为两个不同的目标,它与只有一个规则具有相同的效果:运行配方一次更新两个目标并且 make 只运行配方一次。

如果您使用支持并行构建的 GNU make 或其他一些 make,则此行为不再有效,因为 make 可能会在 rule1 的配方之前检测到 rule2 已过期有机会再更新。但是,那不是 POSIX。

我无法解释为什么 nmake 不能像这样工作...这是一个非常奇怪且有限的 make 实现。

在 POSIX 中处理此问题的传统方法是引入一个“哨兵文件”,将这些多个目标收集为一个,如下所示:

rule1 rule2 : sentinel ;

sentinel: rule3
         @echo creating rule1 and rule2
         @touch rule1 rule2
         @touch $@

我不知道这样的东西在 nmake 中是否有效。

如果您使用 GNU make,它会起作用,或者如果您使用当前版本 (4.3),您可以显式声明分组目标,如下所示:

rule1 rule2 &: rule3
         @echo creating rule1 and rule2
         @touch rule1 rule2