makefile规则

时间:2016-03-29 21:08:45

标签: makefile

我正在尝试找到一种将类似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命令或复制必须执行的操作以完成规则中的操作。

1 个答案:

答案 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

那里没有“通配符”。左侧没有%, 它不是模式规则,右侧的%仅仅意味着%

但你不需要这个。您必须知道先决条件的名称 想要锁定或至少能够使用makefunctions计算它们。 否则你根本不能写makefile。所以说它们是ina inb inc。 然后你将所有锁定为中间,如:

inputs := ina inb inc
locks := $(patsubst %,%.lock,$(inputs))

.INTERMEDIATE: $(locks)