summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2013-01-04 17:39:01 (GMT)
committerEvan Martin <martine@danga.com>2013-04-08 21:45:07 (GMT)
commit85a4db7822d1b433eff8cf9f94f8f1dab3f0b23d (patch)
treeb5fbd90896931bb1ffbaedf25739dd2f3e84d2b4 /src
parentc683ca7d0d9281ef8fc7cb2c4ec022ebc861b745 (diff)
downloadNinja-85a4db7822d1b433eff8cf9f94f8f1dab3f0b23d.zip
Ninja-85a4db7822d1b433eff8cf9f94f8f1dab3f0b23d.tar.gz
Ninja-85a4db7822d1b433eff8cf9f94f8f1dab3f0b23d.tar.bz2
add "special=gcc" attribute, use to load depslog
Diffstat (limited to 'src')
-rw-r--r--src/graph.cc44
-rw-r--r--src/graph.h11
2 files changed, 44 insertions, 11 deletions
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);