diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2012-02-28 02:14:03 (GMT) |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2012-03-01 04:19:57 (GMT) |
commit | af38b5730f670bd4507ced5fc26fb6d2074cf3ac (patch) | |
tree | d99aa279956b7f2a8fbb10b8f28010abb9d93f31 /src/build.cc | |
parent | 3bfbb4ed0a8643a68fa7394303eaf2b3a5f2ca38 (diff) | |
download | Ninja-af38b5730f670bd4507ced5fc26fb6d2074cf3ac.zip Ninja-af38b5730f670bd4507ced5fc26fb6d2074cf3ac.tar.gz Ninja-af38b5730f670bd4507ced5fc26fb6d2074cf3ac.tar.bz2 |
Be more selective about deleting output files when interrupted
Specifically, only delete if the file was modified or if the rule uses
a depfile.
Fixes issue #226.
Diffstat (limited to 'src/build.cc')
-rw-r--r-- | src/build.cc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/build.cc b/src/build.cc index cd73487..44c1df6 100644 --- a/src/build.cc +++ b/src/build.cc @@ -521,16 +521,31 @@ Builder::Builder(State* state, const BuildConfig& config) } Builder::~Builder() { + Cleanup(); +} + +void Builder::Cleanup() { if (command_runner_.get()) { vector<Edge*> active_edges = command_runner_->GetActiveEdges(); command_runner_->Abort(); for (vector<Edge*>::iterator i = active_edges.begin(); i != active_edges.end(); ++i) { + bool has_depfile = !(*i)->rule_->depfile().empty(); for (vector<Node*>::iterator ni = (*i)->outputs_.begin(); - ni != (*i)->outputs_.end(); ++ni) - disk_interface_->RemoveFile((*ni)->path()); - if (!(*i)->rule_->depfile().empty()) + ni != (*i)->outputs_.end(); ++ni) { + // Only delete this output if it was actually modified. This is + // important for things like the generator where we don't want to + // delete the manifest file if we can avoid it. But if the rule + // uses a depfile, always delete. (Consider the case where we + // need to rebuild an output because of a modified header file + // mentioned in a depfile, and the command touches its depfile + // but is interrupted before it touches its output file.) + if (has_depfile || + (*ni)->mtime() != disk_interface_->Stat((*ni)->path())) + disk_interface_->RemoveFile((*ni)->path()); + } + if (has_depfile) disk_interface_->RemoveFile((*i)->EvaluateDepFile()); } } |