diff options
-rw-r--r-- | misc/ninja_syntax.py | 4 | ||||
-rw-r--r-- | src/graph.cc | 44 | ||||
-rw-r--r-- | src/graph.h | 11 |
3 files changed, 47 insertions, 12 deletions
diff --git a/misc/ninja_syntax.py b/misc/ninja_syntax.py index ece7eb5..519330e 100644 --- a/misc/ninja_syntax.py +++ b/misc/ninja_syntax.py @@ -38,7 +38,7 @@ class Writer(object): def rule(self, name, command, description=None, depfile=None, generator=False, pool=None, restat=False, rspfile=None, - rspfile_content=None): + rspfile_content=None, special=None): self._line('rule %s' % name) self.variable('command', command, indent=1) if description: @@ -55,6 +55,8 @@ class Writer(object): self.variable('rspfile', rspfile, indent=1) if rspfile_content: self.variable('rspfile_content', rspfile_content, indent=1) + if special: + self.variable('special', special, indent=1) def build(self, outputs, rule, inputs=None, implicit=None, order_only=None, variables=None): diff --git a/src/graph.cc b/src/graph.cc index 43f4304..2f86785 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -53,22 +53,19 @@ bool Rule::IsReservedBinding(const string& var) { var == "pool" || var == "restat" || var == "rspfile" || - var == "rspfile_content"; + var == "rspfile_content" || + var == "special"; } bool DependencyScan::RecomputeDirty(Edge* edge, string* err) { bool dirty = false; edge->outputs_ready_ = true; - string depfile = edge->GetBinding("depfile"); - if (!depfile.empty()) { - if (!dep_loader_.LoadDepFile(edge, depfile, err)) { - if (!err->empty()) - return false; - EXPLAIN("Edge targets are dirty because depfile '%s' is missing", - depfile.c_str()); - dirty = true; - } + if (!dep_loader_.LoadDeps(edge, err)) { + if (!err->empty()) + return false; + // Failed to load dependency info: rebuild to regenerate it. + dirty = true; } // Visit all inputs; we're dirty if any of the inputs are dirty. @@ -325,6 +322,33 @@ void Node::Dump(const char* prefix) const { } } +bool ImplicitDepLoader::LoadDeps(Edge* edge, string* err) { + string special = edge->GetBinding("special"); + if (!special.empty() && special == "gcc") { + if (!LoadDepsFromLog(edge, err)) { + if (!err->empty()) + return false; + EXPLAIN("deps for %s are missing", edge->outputs_[0]->path().c_str()); + return false; + } + return true; + } + + string depfile = edge->GetBinding("depfile"); + if (!depfile.empty()) { + if (!LoadDepFile(edge, depfile, err)) { + if (!err->empty()) + return false; + EXPLAIN("depfile '%s' is missing", depfile.c_str()); + return false; + } + return true; + } + + // No deps to load. + return true; +} + bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path, string* err) { METRIC_RECORD("depfile load"); diff --git a/src/graph.h b/src/graph.h index d943702..a7b60db 100644 --- a/src/graph.h +++ b/src/graph.h @@ -192,10 +192,19 @@ struct ImplicitDepLoader { DiskInterface* disk_interface) : state_(state), disk_interface_(disk_interface), deps_log_(deps_log) {} + /// Load implicit dependencies for \a edge. + /// @return false on error (without filling \a err if info is just missing). + bool LoadDeps(Edge* edge, string* err); + + private: + /// Load implicit dependencies for \a edge from a depfile attribute. + /// @return false on error (without filling \a err if info is just missing). bool LoadDepFile(Edge* edge, const string& path, string* err); + + /// 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); - private: /// Preallocate \a count spaces in the input array on \a edge, returning /// an iterator pointing at the first new space. vector<Node*>::iterator PreallocateSpace(Edge* edge, int count); |