在我的GNUmakefile中,我希望有一个使用临时目录的规则。例如:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
如上所述,上述规则在解析规则时创建临时目录。这意味着,即使我不是一直创建out.tar,也会创建许多临时目录。我希望避免我的/tmp被未使用的临时目录所充斥。
是否有一种方法可以使变量仅在触发规则时定义,而不是在定义时定义?
我的主要想法是将mktemp和tar转储到shell脚本中,但这似乎有点不美观。
另一种可能是在触发规则时使用单独的行来设置Make变量。
例如,下面是一个带有两条规则的makefile。如果一个规则触发,它会创建一个临时目录,并将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
在您的示例中,每当计算out.tar的规则时,都会设置TMP变量(并创建临时目录)。为了只在out.tar实际触发时创建目录,你需要将目录创建移动到下面的步骤:
out.tar :
$(eval TMP := $(shell mktemp -d))
@echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
eval函数计算一个字符串,就好像它是手动输入到makefile中的一样。在本例中,它将TMP变量设置为shell函数调用的结果。
编辑(回应意见):
要创建一个唯一的变量,您可以执行以下操作:
out.tar :
$(eval $@_TMP := $(shell mktemp -d))
@echo hi $($@_TMP)/hi.txt
tar -C $($@_TMP) cf $@ .
rm -rf $($@_TMP)
这将在变量前加上目标名称(在本例中是out.tar),生成一个名为out.tar_TMP的变量。希望这足以防止冲突。
另一种可能是在触发规则时使用单独的行来设置Make变量。
例如,下面是一个带有两条规则的makefile。如果一个规则触发,它会创建一个临时目录,并将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