diff options
-rw-r--r-- | src/build.cc | 2 | ||||
-rw-r--r-- | src/graph.cc | 20 | ||||
-rw-r--r-- | src/graph.h | 8 |
3 files changed, 21 insertions, 9 deletions
diff --git a/src/build.cc b/src/build.cc index df208af..ecde4df 100644 --- a/src/build.cc +++ b/src/build.cc @@ -516,7 +516,7 @@ void Plan::CleanNode(DependencyScan* scan, Node* node) { if (!(*ni)->dirty()) continue; - if (scan->RecomputeOutputDirty(*ei, most_recent_input, + if (scan->RecomputeOutputDirty(*ei, most_recent_input, 0, command, *ni)) { (*ni)->MarkDirty(); all_outputs_clean = false; diff --git a/src/graph.cc b/src/graph.cc index b11973f..5cc491b 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -61,7 +61,8 @@ bool DependencyScan::RecomputeDirty(Edge* edge, string* err) { bool dirty = false; edge->outputs_ready_ = true; - if (!dep_loader_.LoadDeps(edge, err)) { + TimeStamp deps_mtime = 0; + if (!dep_loader_.LoadDeps(edge, &deps_mtime, err)) { if (!err->empty()) return false; // Failed to load dependency info: rebuild to regenerate it. @@ -112,7 +113,8 @@ bool DependencyScan::RecomputeDirty(Edge* edge, string* err) { for (vector<Node*>::iterator i = edge->outputs_.begin(); i != edge->outputs_.end(); ++i) { (*i)->StatIfNecessary(disk_interface_); - if (RecomputeOutputDirty(edge, most_recent_input, command, *i)) { + if (RecomputeOutputDirty(edge, most_recent_input, deps_mtime, + command, *i)) { dirty = true; break; } @@ -141,6 +143,7 @@ bool DependencyScan::RecomputeDirty(Edge* edge, string* err) { bool DependencyScan::RecomputeOutputDirty(Edge* edge, Node* most_recent_input, + TimeStamp deps_mtime, const string& command, Node* output) { if (edge->is_phony()) { @@ -182,6 +185,12 @@ bool DependencyScan::RecomputeOutputDirty(Edge* edge, } } + // Dirty if the output is newer than the deps. + if (deps_mtime && output->mtime() > deps_mtime) { + EXPLAIN("stored deps info out of date for for %s", output->path().c_str()); + return true; + } + // May also be dirty due to the command changing since the last build. // But if this is a generator rule, the command changing does not make us // dirty. @@ -322,10 +331,10 @@ void Node::Dump(const char* prefix) const { } } -bool ImplicitDepLoader::LoadDeps(Edge* edge, string* err) { +bool ImplicitDepLoader::LoadDeps(Edge* edge, TimeStamp* mtime, string* err) { string deps_type = edge->GetBinding("deps"); if (!deps_type.empty()) { - if (!LoadDepsFromLog(edge, err)) { + if (!LoadDepsFromLog(edge, mtime, err)) { if (!err->empty()) return false; EXPLAIN("deps for %s are missing", edge->outputs_[0]->path().c_str()); @@ -396,7 +405,8 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path, return true; } -bool ImplicitDepLoader::LoadDepsFromLog(Edge* edge, string* err) { +bool ImplicitDepLoader::LoadDepsFromLog(Edge* edge, TimeStamp* deps_mtime, + string* err) { DepsLog::Deps* deps = deps_log_->GetDeps(edge->outputs_[0]); if (!deps) return false; diff --git a/src/graph.h b/src/graph.h index 650a83e..428ba01 100644 --- a/src/graph.h +++ b/src/graph.h @@ -192,9 +192,10 @@ struct ImplicitDepLoader { DiskInterface* disk_interface) : state_(state), disk_interface_(disk_interface), deps_log_(deps_log) {} - /// Load implicit dependencies for \a edge. + /// Load implicit dependencies for \a edge. May fill in \a mtime with + /// the timestamp of the loaded information. /// @return false on error (without filling \a err if info is just missing). - bool LoadDeps(Edge* edge, string* err); + bool LoadDeps(Edge* edge, TimeStamp* mtime, string* err); DepsLog* deps_log() const { return deps_log_; @@ -207,7 +208,7 @@ struct ImplicitDepLoader { /// Load implicit dependencies for \a edge from the DepsLog. /// @return false on error (without filling \a err if info is just missing). - bool LoadDepsFromLog(Edge* edge, string* err); + bool LoadDepsFromLog(Edge* edge, TimeStamp* mtime, string* err); /// Preallocate \a count spaces in the input array on \a edge, returning /// an iterator pointing at the first new space. @@ -242,6 +243,7 @@ struct DependencyScan { /// Recompute whether a given single output should be marked dirty. /// Returns true if so. bool RecomputeOutputDirty(Edge* edge, Node* most_recent_input, + TimeStamp deps_mtime, const string& command, Node* output); BuildLog* build_log() const { |