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