summaryrefslogtreecommitdiffstats
path: root/src/build.cc
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2012-02-28 02:14:03 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2012-03-01 04:19:57 (GMT)
commitaf38b5730f670bd4507ced5fc26fb6d2074cf3ac (patch)
treed99aa279956b7f2a8fbb10b8f28010abb9d93f31 /src/build.cc
parent3bfbb4ed0a8643a68fa7394303eaf2b3a5f2ca38 (diff)
downloadNinja-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.cc21
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());
}
}