Makefile:只有在执行其他规则时才始终执行的规则

Makefile:只有在执行其他规则时才始终执行的规则,makefile,Makefile,我有这个: .PHONY: all shared_setup all: foo bar shared_setup: # do some stuff that always needs to be done if 'foo' or 'bar' run # but shouldn't be done if neither 'foo' nor 'bar' run foo: shared_setup some_other_foo_prerequisite # do somet

我有这个:

.PHONY: all shared_setup
all: foo bar

shared_setup:
    # do some stuff that always needs to be done if 'foo' or 'bar' run
    # but shouldn't be done if neither 'foo' nor 'bar' run

foo: shared_setup some_other_foo_prerequisite
    # do something that depends on shared_setup
    touch foo

bar: shared_setup some_other_bar_prerequisite
    # do something else that depends on shared_setup
    touch bar

当我运行
make all
时,如果执行了
foo
bar
,我希望始终执行
shared\u设置
,但不会导致
foo
bar
被视为过期。另外请注意,如果
foo
bar
都不运行,则
shared\u setup
不应运行。

您可以将
shared\u setup
设置为
foo
bar
的一个(与正常先决条件相反)(注意
符号):

这样,执行规则
shared\u setup
既不会导致
foo
也不会导致
bar
过时


作为“防止每次执行”
shared\u安装程序
的一种解决方法,您可以创建(非
private
必须运行共享安装程序
。让我们考虑一下<代码> Foo目标:

foo: must-run-shared-setup := $(filter $|, $?)
foo: some_other_foo_prerequisite | shared_setup
    ....
自动变量
$?
包含比目标
foo
更新的所有先决条件(无论是普通还是仅限订单)的名称,
$
包含所有
foo
的仅限订单先决条件的名称(即:
对于
foo
,仅限且始终
共享的
设置)

由于我们正在将
必须运行共享设置设置为从
$?
中筛选
$
内容的结果,因此如果必须更新
foo
,则
必须运行共享设置变量将为非空,否则为空

这样,内部
shared\u setup
的配方可以根据此变量的内容有条件地决定是否执行某项操作
必须运行shared setup
(即:实际上它是否为空)

您可以对
目标进行类似操作

更简单的解决方案 这个解决方案意味着改变你的设计,但对我来说似乎简单得多。它包括使用一个空文件,
shared_target
,作为一个简单的时间戳,以便
make
可以确定是否应该运行它

您可以从虚假目标列表中删除
shared_setup
。然后,将其作为仅限订单的先决条件添加到
foo
bar
<代码>共享_设置
应具有
foo
bar
的所有其他先决条件,其配方应将其创建为空文件

.PHONY: all
all: foo bar

shared_setup: some_other_foo_prerequisite some_other_bar_prerequisite
    # do some stuff that always needs to be done if 'foo' or 'bar' run
    # but shouldn't be done if neither 'foo' nor 'bar' run
    touch shared_setup 

foo: some_other_foo_prerequisite | shared_setup
    # do something that depends on shared_setup
    touch foo

bar: some_other_bar_prerequisite | shared_setup
    # do something else that depends on shared_setup
    touch bar

如果
foo
bar
必须更新,因为它们的任何先决条件都已更改,那么
shared\u设置也必须更新。如果
foo
bar
都不需要更新,
shared\u setup
也不需要更新,因为目标
shared\u setup
已经存在,它们的先决条件也不更新。

啊,是的,我最初尝试过这一点,但这里的问题是
shared\u setup
现在总是执行,即使
foo
bar
都不是,这可能是因为
shared\u setup
是生成文件中出现的第一个目标,您可以尝试将其放在末尾。您如何调用
确保
?当然,我更新了我的问题,以便更好地说明我想要什么@水飲み鳥 您将共享_设置列为foo和bar的纯订单依赖项和非纯订单依赖项。@HardcoreHenry更正。非常感谢:-)
.PHONY: all
all: foo bar

shared_setup: some_other_foo_prerequisite some_other_bar_prerequisite
    # do some stuff that always needs to be done if 'foo' or 'bar' run
    # but shouldn't be done if neither 'foo' nor 'bar' run
    touch shared_setup 

foo: some_other_foo_prerequisite | shared_setup
    # do something that depends on shared_setup
    touch foo

bar: some_other_bar_prerequisite | shared_setup
    # do something else that depends on shared_setup
    touch bar