我知道以前曾经问过这个问题,但我找不到任何解决方案,因为他们反抗DRY。
我有许多目标依赖于无法随时加盖时间的内容 - 例如从其他系统复制的文件。我喜欢能够做的是在变量中列出依赖关系,例如nobuild=this,that
,并且假定的目标是 - 至今。由于我有很多这些,我不希望每个人ifdef
周围;什么是伪可能的首选将是像
ignorable-target: dependencies
$(call ifnobuild,$@)
.. rest of normal build steps ..
如果在ifnobuild
中提到gmake
,ignorable-target
宏扩展到某种退出此配方与成功 nobuild
指令的位置gmake
变量。
我也没有想要进入多行继续shell命令,以便将条件推迟到配方本身;我希望能够告诉make"假设这些目标是最新的,并且不会尝试构建它们,"所以我可以用已经从有问题的食谱中获得的本地副本测试其他方面。
remote1
中有不是任何退出配方成功机制吗?
[编辑希望能让情况更清楚。]
这是一个例子。目标remote2
和ssh
均涉及使用local1
在远程系统上执行耗时的操作,然后在本地复制结果。目标target-under-work
是在本地构建的,并不是时间汇。 local1: local1.c Makefile
remote1: local1
scp local1 remote-host:/tmp/
ssh remote-host /tmp/local1 some-args # takes a long time
scp remote-host:/tmp/local1.out remote1
remote2: local1
scp local1 other-host:/tmp/
ssh other-host /tmp/local1 other-args # takes a long time
scp other-host:/tmp/local1.out remote2
target-under-work: local1 remote1 remote2
do-something-with remote1,remote2
取决于上述所有三个。
make target-under-work
现在,当我运行remote1
时,它会运行remote2
和target-under-work
的食谱。但是,这些文件的本地副本足够好'对于我的测试,所以我不要希望它们每次都运行。一旦投入生产,他们将每次都运行,但在我开发remote1
时,我只想使用已经构建的副本,我可以每天重建它们(或其他)用于必要的测试粒度。
上述内容过于简化;有多个步骤和目标取决于remote2
和/或remote1
。我看到如何通过使它们成为仅限订单的先决条件来获得我想要的效果 - 但这将意味着更改将其作为先决条件的每个目标的依赖关系列表,而不是将单个更改为remote2
和EventTimestamp
EventDescription
所以我可以使用命令行中的一些变量来告诉他们的食谱并假装已经构建了这些变量,如果已经构建它,请不要实际构建它副本。'
我希望这会使我的问题更清楚。
答案 0 :(得分:1)
不,这个早期退出制作功能不存在。
请注意,您的问题可能未明确指定,因为您尚未解释当慢目标尚不存在时您想要的行为。
假设nobuild
中列出的慢速目标只有当它们不存在时才会被重建。您可以使用make函数“隐藏”其先决条件列表,而不是使用make函数提前退出其配方。这样,如果它们已经存在,即使它们已经过时,它们也不会被重建。唯一的细微之处在于,您需要第二次扩展才能在先决条件列表中使用$@
自动变量。在以下示例中,slow
(您的remoteX
)取决于fast1
(您的local1
)。 fast2
(您的target-under-work
)取决于fast1
和slow
:
host> cat Makefile
# Expands as empty string if $(1) exists and
# listed in $(nobuild). Else expands as $(2).
# $(1): target
# $(2): prerequisites
define HIDE_IF_NOBUILD
$(if $(wildcard $(1)),$(if $(filter $(1),$(nobuild)),,$(2)),$(2))
endef
nobuild :=
fast1:
@echo 'build $@'
@touch $@
fast2: fast1 slow
@echo 'build $@'
@touch $@
.SECONDEXPANSION:
slow: $$(call HIDE_IF_NOBUILD,$$@,fast1)
@echo 'build $@'
@touch $@
# Case 1: slow target not listed in nobuild and not existing
host> rm -f slow; touch fast1; make fast2
build slow
build fast2
# Case 2: slow target not listed in nobuild and existing and outdated
host> touch slow; sleep 2; touch fast1; make fast2
build slow
build fast2
# Case 3: slow target listed in nobuild and not existing
host> rm -f slow; touch fast1; make nobuild="slow" fast2
build slow
build fast2
# Case 4: slow target listed in nobuild and existing and outdated
host> touch slow; sleep 2; touch fast1; make nobuild="slow" fast2
build fast2