在规则执行时定义makevariables

在我的GNUmakefile中,我想要一个使用临时目录的规则。 例如:

out.tar: TMP := $(shell mktemp -d) echo hi $(TMP)/hi.txt tar -C $(TMP) cf $@ . rm -rf $(TMP) 

如上所述,上述规则在parsing规则时创build临时目录。 这意味着,即使我一直做不出out.tar,也会创build许多临时目录。 我想避免我的/ tmp乱丢未使用的临时目录。

有什么办法可以让这个variables只在规则被触发时被定义,而不是每当它被定义的时候呢?

我的主要想法是将mktemp和tar转储到shell脚本中,但这看起来有点难看。

在你的例子中,只要计算out.tar规则 ,就会设置TMPvariables(以及创build的临时目录)。 为了仅在out.tar被实际触发时创build目录,您需要将目录创build向下移动到以下步骤:

 out.tar : $(eval TMP := $(shell mktemp -d)) @echo hi $(TMP)/hi.txt tar -C $(TMP) cf $@ . rm -rf $(TMP) 

eval函数评估一个string,就像手动input到makefile中一样。 在这种情况下,它将TMPvariables设置为shell函数调用的结果。

编辑 (回复评论):

要创build一个唯一的variables,您可以执行以下操作:

 out.tar : $(eval $@_TMP := $(shell mktemp -d)) @echo hi $($@_TMP)/hi.txt tar -C $($@_TMP) cf $@ . rm -rf $($@_TMP) 

这会将目标名称(out.tar,在这种情况下)添加到variables中,生成名称为out.tar_TMP的variables。 希望这足以防止冲突。

这样做的一个相对简单的方法是将整个序列写成一个shell脚本。

 out.tar: set -e ;\ TMP=$$(mktemp -d) ;\ echo hi $$TMP/hi.txt ;\ tar -C $$TMP cf $@ . ;\ rm -rf $$TMP ;\ 

我在这里合并了一些相关的技巧: https : //stackoverflow.com/a/29085684/86967

另一种可能是在规则触发时使用单独的行来设置Makevariables。

例如,这里有两个规则的makefile。 如果规则触发,它将创build一个临时目录并将TMP设置为临时目录名称。

 PHONY = ruleA ruleB display all: ruleA ruleA: TMP = $(shell mktemp -d testruleA_XXXX) ruleA: display ruleB: TMP = $(shell mktemp -d testruleB_XXXX) ruleB: display display: echo ${TMP} 

运行代码会产生预期的结果:

 $ ls Makefile $ make ruleB echo testruleB_Y4Ow testruleB_Y4Ow $ ls Makefile testruleB_Y4Ow