我有这个:
.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
时,如果shared_setup
或foo
被执行,我希望始终执行bar
,但不要导致foo
或{{ 1}}被认为已过时。另请注意,如果bar
和shared_setupd
都没有运行,foo
就不会运行。
答案 0 :(得分:1)
您可以shared_setup
foo
和bar
{em} order-only prerequisite (而不是正常先决条件) (注意|
符号):
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: 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
这样,执行规则shared_setup
将导致foo
和bar
都不会过时。
作为每次“阻止”shared_setup
执行的解决方法,您可以创建(非private
) target-specific variable {{1} }。让我们考虑一下must-run-shared-setup
目标:
foo
自动变量foo: must-run-shared-setup := $(filter $|, $?)
foo: some_other_foo_prerequisite | shared_setup
....
包含比目标{{1}更新的所有先决条件(无论是正常还是仅订单)的名称},$?
包含所有foo
仅限订单的先决条件的名称(即:仅{,1 {}} $|
。
由于我们将foo
设置为从shared_setup
过滤foo
的内容的结果,如果must-run-shared-setup
$|
变量将为非空必须更新,否则为空。
这样,根据此变量$?
的内容(即:实际上是否为空),可以有条件地决定内部must-run-shared-setup
的配方是否做某事。
您可以类似地执行foo
目标。
这个解决方案意味着改变你的设计,但对我来说似乎更简单。它包含使用空文件shared_setup
作为简单时间戳,以便must-run-shared-setup
可以确定是否应该运行它。
您可以从虚假目标列表中删除bar
。然后,将其添加为shared_target
和make
的仅订单先决条件。 shared_setup
应具有foo
和bar
的所有其他先决条件,其配方应将其创建为空文件。
shared_setup
如果由于任何先决条件发生变化而必须更新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_setup
也不需要更新,因为目标foo
已经存在,而且它们的先决条件并不新。