GNU Make包含一个名为.DELETE_ON_ERROR
的特殊目标。如果这包含在Makefile中,Make将删除其构建序列以非零返回状态完成的任何目标。这很有用,因此在后续调用中,Make不会假定目标已正确构建。
这是一个虚拟的例子。
.DELETE_ON_ERROR:
out.dat: in.dat
touch out.dat
false
由于false
提供非零返回值,因此构建被视为失败,并且Make会删除out.dat
目标。这是广告和预期的行为。但是,当目标是目录时,似乎不会保留此行为。考虑另一个虚拟的例子。
.DELETE_ON_ERROR:
outdir/: in.dat
mkdir outdir/
false
在这种情况下,构建再次失败,但Make不会删除outdir
目录。 有什么方法可以指示Make这样做吗?
答案 0 :(得分:1)
如注释中所述,很难在目录上使用时间戳。几种选择:
使用代理目标,可以将Makefile修改为包括一个'%.done'目标,该目标将嵌入清除逻辑。
.PHONY: %.dir
outdir.dir:
$(MAKE) outdir ; if [ $? -ne 0 ] ; then echo CLEANUP $@ ; rm -rf dir ; false ; fi
outdir: ... # as before
并使用outdir.dir作为依赖项。不优雅,但是可以完成工作。可能可以转换为规则(免责声明:我没有测试这种方法)。
.PHONY %.dir
%.dir:
$(MAKE) $* ; if [ $? -ne 0 ] ; then echo CLEANUP $* ; rmd -rf $* ; false ; fi
另一种变化是更改outdir以添加“完成”指示符文件(如果成功完成),并使用代理目标进行验证
%.dir:
$(MAKE) $* ; if [ ! -f $*.done ] ; then rm -rf $* ; false ; fi
outdir:
... commands, any can fail.
touch $*.done
作为最后的选择(或根据您的情况,选择第一种方法),请考虑为outdir'atomic'构建-创建一个临时文件夹,并在成功后将其重命名为outdir
outdir:
rm -rf $@.new $@
mkdir $@.new
# Command to create outdir.new here
mv $@.new $@