当前位置:  开发笔记 > 编程语言 > 正文

为什么在先决条件之前运行配方?

如何解决《为什么在先决条件之前运行配方?》经验,为你挑选了1个好方法。

我有一个带有一些模式规则¹的make文件,最终成为另一个规则的先决条件.显示我困惑的症状的最小例子是:

.PHONY: clean default one two

default: clean one two

clean:
    @rm -f {one,two}.{a,b}

one two: %: %.a %.b
    @echo TARGET $@ PREREQUISITES $^

%.a %.b:
    @echo Prereq $@
    @touch $@

运行它时我期望的输出是:

Prereq one.a Prereq
one.b
TARGET one PRACQUISITES one.a
one.b Prereq two.a Prereq
two.b
目标两个PREREQUISITES two.a two.b

相反,只有第一个先决条件被构建,make给我这个:

Prereq one.a
TARGET one PRACQUISITES one.a one.b Prereq
two.a
TARGET两个PREREQUISITES two.a two.b

正如您所看到的,配方本身正确地解析这些并知道它应该在两个先决条件之后构建,但实际上并未运行先决条件规则.

顺便说一下,我在这里使用第二项的仅订单先决条件,但这并不重要:同样的问题无论如何都表现出来.

如果我第二次运行相同的目标,那么它构建第二个先决条件.换句话说,两次传球最终得到了我需要的结果:

$ make clean
$ make one
Prereq one.a
TARGET one PREREQUISITES one.a one.b
$ make one
Prereq one.b
TARGET one PREREQUISITES one.a one.b

它第一次运行时,只存在第一个先决条件而且我已经破了one.在第二遍one.a存在,所以它决定建立one.b.既然两个先决条件都存在我的one构建正确.

如果我将先决条件目标变体拼写为两个单独的配方(分别为两个%a:%.b模式重复相同的块),则为每个目标构建两个先决条件.然而,这会使我的文件更复杂,我想了解为什么这会破坏.


¹ 这个make文件有一些其他的问题,但我已经把这个问题分离成一个可重现的案例,所以我不认为它的其他特性是这里的问题.



1> giusti..:

GNU Make具有我们可能认为有点"怪癖"的意义,因为多目标模式规则不像几个规则那样起作用.在这种情况下,规则仅由单个目标触发一次,并且Make期望规则立即生成所有目标.从GNU Make文档:

模式规则可能有多个目标.与普通规则不同,这并不会使用相同的先决条件和配方来执行许多不同的规则.如果模式规则具有多个目标,则make知道规则的配方负责制作所有目标.配方仅执行一次以制作所有目标.[...]

那么这里发生的是:

    检查依赖关系one:find one.aone.bfrom pattern %: %.a %.b;

    找到一个图案规则两者one.aone.b;

    执行配方,将target($@)设置为one.a(触发规则的那个);

    标记两者one.aone.b更新,即使仅创建了配方one.a;

    认为所有依赖one关系已经满足并继续做同样的事情two.

Make再次调用它时触摸不同文件的原因是因为现在one.a并且two.a是最新的.因此触发规则的目标变为one.btwo.b.如果您one.a在调用Make第二次之前删除它,它将创建one.atwo.b.

所以你至少有三种可能的解决方案.一个是拼出那些表现得像你期望的目标 - 你说这不是一个好的解决方案,但无论如何都值得一提.另一个是将其分解%.a %.b为两个规则,这两个规则实现相同但考虑到您的需求可能更容易.第三个是在同一个配方中执行Make期望并创建两个目标 - 例如,您可以在配方中使用词干:

%.a %.b:
        @echo Processing target $@ from stem $*
        touch $*.a $*.b

在研究这个问题时我注意到的另一件事是你的MCVE clean被打破了.默认情况下,Make会使用/bin/sh,这不会扩展{a,b}.您可以设置SHELL=/bin/bash更改它.

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有