当前位置:  开发笔记 > 编程语言 > 正文

为什么GNU会删除文件

如何解决《为什么GNU会删除文件》经验,为你挑选了3个好方法。

我有一个稍微hackish makefile用于运行测试:

### Run the tests

tests := tests/test1 tests/test2 ...

test: $(tests)

$(tests): %: %.c
    gcc -o $@ $(testflags) $<
    $@

它有效,但它使Make做了我以前从未见过的事情.我的测试目前已被破坏,并导致总线错误.Make提供以下输出:

gcc -o tests/test1 [flags blah blah] tests/test1.c
tests/test1
make: *** [tests/test1] Bus error
make: *** Deleting file `tests/test1'

我对最后一行感到好奇.我以前从未见过Make.为什么Make删除已编译的测试?

注意:我非常重视这个例子以使其更简单.我可能会介绍一些错误.



1> Jon Ericson..:

因为目标可能没有正确构建.下次您执行make该项目时,它将尝试重建目标.如果文件没有删除,make就无法知道出了什么问题. make无法知道失败来自测试而不是构建目标的过程.


在您的情况下,这种行为是否合适取决于测试的性质.如果您计划修复测试以使其不会导致测试,那么Bus error移除目标并不是什么大问题.如果您希望稍后使用目标进行调试,则需要对make进程进行更改.

不删除目标的一种方法是使用.PRECIOUS目标.


另一个可能是:

$(tests): %: %.c
    gcc -o $@ $(testflags) $<
    -$@

未经测试,但文档表明目标不会被删除:

当一个错误发生时,make没有被告知忽略,这意味着当前目标无法正确重新制作,也不能直接或间接地依赖它.不会对这些目标执行进一步的命令,因为它们的先决条件尚未实现.

和:

通常,当命令失败时,如果它完全更改了目标文件,则该文件已损坏且无法使用 - 或者至少未完全更新.然而文件的时间戳表示它现在是最新的,所以下次make运行时,它不会尝试更新该文件.情况与命令被信号杀死时的情况相同; 看到中断.因此,通常正确的做法是在开始更改文件后如果命令失败则删除目标文件.如果.DELETE_ON_ERROR作为目标出现,make将执行此操作.这几乎总是你想要做的事情,但这不是历史实践; 因此,为了兼容性,您必须明确请求它.



2> Greg Hewgill..:

避免此行为的一种方法是将构建和测试执行分为两个步骤:

tests := tests/test1 tests/test2 ...

test: $(tests) runtests

$(tests): %: %.c
    gcc -o $@ $(testflags) $<

runtests: %.out: %
    $< | tee $@

(我的make语法可能存在错误,任何人都可以随意纠正它.)一般的想法是让测试运行生成一个输出文件,这样可以更容易make地单独运行每个测试.


+1是指出该行为是由错误的Makefile引起的唯一答案,该错误的Makefile结合了生成测试程序并将其运行为一条规则的过程。

3> 小智..:

这是make的默认行为.当命令返回错误代码(例如非零返回)时,将删除make目标..PRECIOUS和.IGNORE makefile指令可以更改此行为.

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有