在规则执行时定义make变量

在我的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脚本中,但这似乎有些难看。


鸿蒙传说
浏览 569回答 3
3回答

慕婉清6462132

在您的示例中,TMP只要评估了规则,out.tar便会设置变量(并创建临时目录)。为了仅在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 displayall: ruleAruleA: TMP = $(shell mktemp -d testruleA_XXXX)ruleA: displayruleB: TMP = $(shell mktemp -d testruleB_XXXX)ruleB: displaydisplay:    echo ${TMP}运行代码会产生预期的结果:$ lsMakefile$ make ruleBecho testruleB_Y4OwtestruleB_Y4Ow$ lsMakefile  testruleB_Y4Ow
打开App,查看更多内容
随时随地看视频慕课网APP