我正在尝试找到一种将类似RAII的动作添加到我正在维护的makefile中的好方法。目前,我有类似的东西:
out: in
lockfile in.lock
echo in // Some action which can fail
rm -f in.lock
这个代码在使用多个作业时工作正常,因为它主要是指理智而不是性能。至少,如果我的行动没有失败。所以如果我想为此添加一个后备。简而言之,它看起来像是:
out: in
lockfile in.lock
(echo in) || (rm -f in.lock; false)
rm -f in.lock
然而再次看起来很好,虽然我不喜欢写两次rm -f in.lock
,如果实际内容是几行bash-script,(echo in)
看起来也不优雅。
这看起来类似于:
out: in
lockfile in.lock
trap "rm -f in.lock" EXIT; \
(echo in)
但是,如果您有不同的规则,这将使实际规则看起来更复杂。
out: in
lockfile in.lock
trap "rm -f in.lock" EXIT; \
$(SHOW_DEPENDENCY_ON_DEBUG) && \
(echo in)
SHOW_DEPENDENCY_ON_DEBUG在某些情况下可以定义为echo $@ <=== $^
,在其他情况下可以定义为@
。所以我不确定我是否可以很好地链接所有命令。因此,我希望你们中的任何人都知道我错过了一些技巧。
简而言之,我喜欢改造:
out: in
lockfile in.lock
echo in // Some action(s) which can fail
rm -f in.lock
总是执行rm -f in.lock
的方式,无需链接bash命令或复制必须执行的操作以完成规则中的操作。
答案 0 :(得分:1)
对于确保您的锁文件(或make
生成的任何文件)被删除的问题,可能会发生以下情况:
make
有一个库存解决方案:将其设为.INTERMEDIATE
target。
然后,如果make
创建了文件,它会在最后自动删除它,例如。
<强>生成文件强>
.PHONY: all clean
all: out
in:
touch $@ # Whatever
.INTERMEDIATE: in.lock
%.lock: %
touch $@ # Whatever
out: in.lock
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch $@; fi
rm -f $<
clean:
rm -f in out
这里有命令:
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch $@; fi
将失败或成功进行伪随机抛硬币。
一些运行:
$ make
touch in # Whatever
touch in.lock # Whatever
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch out; fi
Succeed
rm -f in.lock
$ make clean
rm -f in out
$ make
touch in # Whatever
touch in.lock # Whatever
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch out; fi
Fail
Makefile:14: recipe for target 'out' failed
make: *** [out] Error 1
rm in.lock
但是,除非删除
,否则不要推送此功能rm -f $<
来自食谱。 make
将在退出时删除中间件,如果配方失败,则可以。
但是如果配方成功,你可能会想要立即删除锁定文件而不是删除
make
完成,后来可能是任意的。
<强>后来强>
.INTERMEDIATE可以引用通配符,例如%.lock?
没有。你必须指的是:
.INTERMEDIATE: %.lock
那里没有“通配符”。左侧没有%
,
它不是模式规则,右侧的%
仅仅意味着%
。
但你不需要这个。您必须知道先决条件的名称
想要锁定或至少能够使用make
functions计算它们。
否则你根本不能写makefile。所以说它们是ina inb inc
。
然后你将所有锁定为中间,如:
inputs := ina inb inc
locks := $(patsubst %,%.lock,$(inputs))
.INTERMEDIATE: $(locks)