【发布时间】:2018-11-16 16:11:24
【问题描述】:
我知道以前有人问过这个问题,但我发现没有一个解决方案对我有用,因为它们是抗 DRY 的。
我有许多目标,这些目标依赖于无法轻易添加时间戳的事物,例如从另一个系统复制的文件。我希望能够做的是列出变量中的依赖项,例如nobuild=this,that,并假定这些目标是最新的。因为我有很多这样的,我不想想在每一个周围都ifdef;在伪代码上更可取的是像
ignorable-target: dependencies
$(call ifnobuild,$@)
.. rest of normal build steps ..
如果ignorable-target 在nobuild 变量中被提及,则ifnobuild 宏扩展为某种exit-from-this-recipe-with-success gmake 指令。
我也不想要进入多行连续的shell命令,以便将条件推迟到配方本身;我希望能够告诉 make“假设这些目标是最新的并且不要尝试构建它们”,因此我可以使用已经从有问题的配方中获得的本地副本测试其他方面。
gmake 中没有任何类型的 exit-recipe-with-success 机制,是吗?
[编辑希望能让情况更清楚。]
这是一个例子。目标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。我知道如何通过使它们成为仅订购的先决条件来获得我想要的效果——但这意味着更改将它们作为先决条件的每个目标的依赖关系列表,而不是将 single 更改为remote1 和 remote2 所以我可以使用命令行中的一些变量来告诉他们的食谱“假设它已经构建,如果已经有副本就不要实际构建它。”
我希望这能让我的问题更清楚。
【问题讨论】:
-
如果一个目标永远不会被重建,为什么要为它制定一个规则?这些目标中的任何一个都是其他任何东西的先决条件吗?
-
你知道order-only prerequisites吗?我可能错了,但我怀疑它们可能就是您要寻找的东西。
-
并不是说它们永远不会被重建;他们确实得到重建。但是它们需要很长时间,当我在做依赖于它们的东西时,我想使用我上次构建的东西,而不是再次构建它。没有办法给它们加上时间戳,因为没有办法(不做所有的远程工作)来判断是否有任何变化。我希望能够有选择地说“这不需要重建”;完成后,它们都会正常构建。
标签: makefile build gnu-make exit recipe