Makefile 多目标Gnumake规则

Makefile 多目标Gnumake规则,makefile,gnu-make,targets,Makefile,Gnu Make,Targets,我正在寻找说服gnumake构建“全部”的方法 将规则的目标作为一个单元,并要求在 任何一个目标丢失或丢失都是有原因的 过时了 考虑这个简单的Makefile: b.foo: 触摸b.foo b、 bar1 b.bar2:b.foo 触摸b.bar1 触摸b.bar2 b、 zoo1:b.bar1 触摸b.zoo1 b、 zoo2:b.bar2 触摸b.zoo2 #b.1号楼按预期运行 >make4b.zoo1 触摸b.foo 触摸b.bar1 触摸b.bar2 触摸b.zoo1 >做b.1 m

我正在寻找说服gnumake构建“全部”的方法 将规则的目标作为一个单元,并要求在 任何一个目标丢失或丢失都是有原因的 过时了

考虑这个简单的Makefile:

b.foo:
触摸b.foo
b、 bar1 b.bar2:b.foo
触摸b.bar1
触摸b.bar2
b、 zoo1:b.bar1
触摸b.zoo1
b、 zoo2:b.bar2
触摸b.zoo2
#b.1号楼按预期运行
>make4b.zoo1
触摸b.foo
触摸b.bar1
触摸b.bar2
触摸b.zoo1
>做b.1
make:“b.zoo1”是最新的。
#b.2号楼也按预期运行
>做b.zoo2
触摸b.zoo2
>做b.zoo2
make:“b.zoo2”是最新的。
#现在,我删除了使用第二条规则构建的一个对等点
>b.2室
#我看到b.zoo1保持最新,因为它的依赖关系仍然存在。
#然而,这不是我想要的行为。与b.bar2
#现在不见了,我希望b.zoo1和b.zoo2过时。
>做b.1
make:“b.zoo1”是最新的。
#但事实并非如此。更糟糕的是,构建b.zoo2确实会强制重建b.bar1和b.bar2
>做b.zoo2
触摸b.bar1
触摸b.bar2
触摸b.zoo2
#这使得b.zoo1已经过时了
>做b.1
触摸b.zoo1
那么,有没有办法编写一个规则来构建多个目标,让它们按照我的意愿运行呢?或者有没有一种方法可以使用gnumake标准库
完成此任务?

b.bar1 b.bar2:b.foo
此规则告诉make有两个目标
b.bar1
b.bar2
,这两个目标都依赖于
b.foo
,并且都可以通过列出的规则构建。它不会告诉make它们是通过相同的规则调用生成的相关目标。使用GNU make,您可以使用模式规则(如
%.bar1%.bar2:%.foo
)告诉make关于后一种信息


我不知道我是否完全理解您所解释的问题,但我认为这些信息(以及模式规则)在这里可能有用。

是的,在规则中写入多个目标只是将它们单独写出的简写

b.bar1 b.bar2 : b.foo
    touch b.bar1
    touch b.bar2
完全一样

b.bar1: b.foo
    touch b.bar1
    touch b.bar2

b.bar2: b.foo
    touch b.bar1
    touch b.bar2
显然是错的。你可以写

b.foo:
    touch b.foo

b.bar1: b.foo
    touch b.bar1

b.bar2: b.foo
    touch b.bar2

b.zoo1: b.bar1 b.bar2
    touch b.zoo1

b.zoo2: b.bar1 b.bar2
    touch b.zoo2
使用配方中的
$@
作为目标名称来整理此内容

b.foo:
    touch $@

b.bar1: b.foo
    touch $@

b.bar2: b.foo
    touch $@

b.zoo1: b.bar1 b.bar2
    touch $@

b.zoo2: b.bar1 b.bar2
    touch $@
现在您可以看到规则中的多个目标与单独编写规则一样有用。我们可以这样写

b.foo:
    touch $@

b.bar1 b.bar2: b.foo
    touch $@

b.zoo1 b.zoo2: b.bar1 b.bar2
    touch $@
很好。这将修复您原来的问题


(虽然我怀疑这可能无法解决您的实际问题。
b.bar1
b.bar2
都是由某个实用程序的一次运行创建的吗?

似乎您可以简单地声明zoo1依赖于bar2,而zoo2和bar1则相反。您仍然无法强制“makezoo1”构建zoo2,除非在它们之间引入依赖项,但无论如何,您都不能创建循环依赖项。这方面的实际用例是什么?我使用gnumake进行工程工作流。在这种环境中,许多工具生成多个输出。通常情况下,下游刀具仅取决于先前刀具的一个目标。我不希望后续目标依赖于先前工具的其他目标,这些目标不是真正的依赖关系。然而,重要的是先前工具的多个目标彼此保持一致。。。“我不想…后续目标[依赖于]先前工具的其他目标…但是,重要的是,先前工具的多个目标[存在并]彼此保持一致。”这是什么?在执行下游工具之前,您希望Make确保多个目标存在且一致吗?这就是答案——问题经常出现在GNU Make邮件列表和错误报告中——例如,单个大型规则同时创建多个目标。我们有数百条这样的规则。我不想重复庞大的规则。一个特定的下游目标可能只依赖于这些多个目标中的一个。另一个下游目标可能依赖于这些输出中的另一个。因此,这些目标必须看起来是原子生成的,因为它们是原子生成的。我刚刚发现了一个有趣的工作,在这个工作中你可以工作。但它很难看,而且在运行时很受欢迎。Gnumake默认情况下应该是这样的。@tvarga上面的解决方案与原始公式相匹配,原始公式使用了两个单独的
touch
命令来生成原始的条形文件。如果您有一个命令可以生成两个(或更多)目标(我认为这就是您所拥有的),那么有两个选项:(I)纯模式规则或(ii)哨兵文件。就我个人而言,我不喜欢模式规则的特殊性质,因此转向sentinel文件。这种模式经常发生(例如,在Windows上链接一个.dll会同时抛出一个.pdb和一个.lib文件),但没有多少人正确地编写代码。