Emi*_*Sit 186 makefile gnu-make
在我的GNUmakefile中,我希望有一个使用临时目录的规则.例如:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Run Code Online (Sandbox Code Playgroud)
如上所述,上述规则在解析规则时创建临时目录.这意味着,即使我没有直接创建.tar,也会创建许多临时目录.我想避免我的/ tmp被未使用的临时目录弄乱.
是否有办法使该变量仅在触发规则时定义,而不是在定义时定义?
我的主要想法是将mktemp和tar转储到shell脚本中,但这看起来有点难看.
e.J*_*mes 293
在您的示例中,TMP只要评估规则,就会设置变量(并创建临时目录)out.tar.为了仅在out.tar实际触发时创建目录,您需要将目录创建向下移动到以下步骤中:
out.tar :
$(eval TMP := $(shell mktemp -d))
@echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Run Code Online (Sandbox Code Playgroud)
该EVAL,如果它已经手动键入到makefile文件函数计算的字符串.在这种情况下,它将TMP变量设置为shell函数调用的结果.
编辑(回应评论):
要创建唯一变量,您可以执行以下操作:
out.tar :
$(eval $@_TMP := $(shell mktemp -d))
@echo hi $($@_TMP)/hi.txt
tar -C $($@_TMP) cf $@ .
rm -rf $($@_TMP)
Run Code Online (Sandbox Code Playgroud)
这会将目标的名称(在本例中为out.tar)添加到变量中,从而生成具有名称的变量out.tar_TMP.希望这足以防止冲突.
nob*_*bar 57
执行此操作的一种相对简单的方法是将整个序列编写为shell脚本.
out.tar:
set -e ;\
TMP=$$(mktemp -d) ;\
echo hi $$TMP/hi.txt ;\
tar -C $$TMP cf $@ . ;\
rm -rf $$TMP ;\
Run Code Online (Sandbox Code Playgroud)
我在这里整理了一些相关提示:https://stackoverflow.com/a/29085684/86967
小智 30
另一种可能性是在规则触发时使用单独的行来设置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}
Run Code Online (Sandbox Code Playgroud)
运行代码会产生预期的结果:
$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile testruleB_Y4Ow
Run Code Online (Sandbox Code Playgroud)
我不喜欢“不要”的答案,但是……不要。
make的变量是全局的,应该在 makefile 的“解析”阶段进行评估,而不是在执行阶段进行评估。
在这种情况下,只要变量是单个目标的局部变量,就按照@nobar 的回答并使其成为 shell 变量。
其他 make 实现也认为特定于目标的变量是有害的:kati、Mozilla pymake。由于它们,目标可以不同地构建,具体取决于它是独立构建的,还是作为具有特定于目标的变量的父目标的依赖项。而且你不会知道它是哪一种方式,因为你不知道已经构建了什么。
| 归档时间: |
|
| 查看次数: |
141668 次 |
| 最近记录: |