summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Niklas Hasse <jhasse@bixense.com>2021-08-12 11:42:24 (GMT)
committerGitHub <noreply@github.com>2021-08-12 11:42:24 (GMT)
commitffb47fcf82ed12f53c046f6d51401c34ec35eced (patch)
tree694ad0d96f0b2e25a31be60ae1ee7288f63977ea /src
parentd52a43d105040b92442e7c6657b50a2188b80ebd (diff)
parent0b6be4353e4ee330e9b72228ba768b4f2cb56399 (diff)
downloadNinja-ffb47fcf82ed12f53c046f6d51401c34ec35eced.zip
Ninja-ffb47fcf82ed12f53c046f6d51401c34ec35eced.tar.gz
Ninja-ffb47fcf82ed12f53c046f6d51401c34ec35eced.tar.bz2
Merge pull request #1347 from tzik/revdep
Look up header dependencies on the first-output build
Diffstat (limited to 'src')
-rw-r--r--src/deps_log.cc13
-rw-r--r--src/deps_log.h1
-rw-r--r--src/deps_log_test.cc27
-rw-r--r--src/ninja.cc21
4 files changed, 54 insertions, 8 deletions
diff --git a/src/deps_log.cc b/src/deps_log.cc
index 191f300..7e48b38 100644
--- a/src/deps_log.cc
+++ b/src/deps_log.cc
@@ -295,6 +295,19 @@ DepsLog::Deps* DepsLog::GetDeps(Node* node) {
return deps_[node->id()];
}
+Node* DepsLog::GetFirstReverseDepsNode(Node* node) {
+ for (size_t id = 0; id < deps_.size(); ++id) {
+ Deps* deps = deps_[id];
+ if (!deps)
+ continue;
+ for (int i = 0; i < deps->node_count; ++i) {
+ if (deps->nodes[i] == node)
+ return nodes_[id];
+ }
+ }
+ return NULL;
+}
+
bool DepsLog::Recompact(const string& path, string* err) {
METRIC_RECORD(".ninja_deps recompact");
diff --git a/src/deps_log.h b/src/deps_log.h
index cc44b41..09cc41c 100644
--- a/src/deps_log.h
+++ b/src/deps_log.h
@@ -86,6 +86,7 @@ struct DepsLog {
};
LoadStatus Load(const std::string& path, State* state, std::string* err);
Deps* GetDeps(Node* node);
+ Node* GetFirstReverseDepsNode(Node* node);
/// Rewrite the known log entries, throwing away old data.
bool Recompact(const std::string& path, std::string* err);
diff --git a/src/deps_log_test.cc b/src/deps_log_test.cc
index 4055941..1c29d89 100644
--- a/src/deps_log_test.cc
+++ b/src/deps_log_test.cc
@@ -478,4 +478,31 @@ TEST_F(DepsLogTest, TruncatedRecovery) {
}
}
+TEST_F(DepsLogTest, ReverseDepsNodes) {
+ State state;
+ DepsLog log;
+ string err;
+ EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err));
+ ASSERT_EQ("", err);
+
+ vector<Node*> deps;
+ deps.push_back(state.GetNode("foo.h", 0));
+ deps.push_back(state.GetNode("bar.h", 0));
+ log.RecordDeps(state.GetNode("out.o", 0), 1, deps);
+
+ deps.clear();
+ deps.push_back(state.GetNode("foo.h", 0));
+ deps.push_back(state.GetNode("bar2.h", 0));
+ log.RecordDeps(state.GetNode("out2.o", 0), 2, deps);
+
+ log.Close();
+
+ Node* rev_deps = log.GetFirstReverseDepsNode(state.GetNode("foo.h", 0));
+ EXPECT_TRUE(rev_deps == state.GetNode("out.o", 0) ||
+ rev_deps == state.GetNode("out2.o", 0));
+
+ rev_deps = log.GetFirstReverseDepsNode(state.GetNode("bar.h", 0));
+ EXPECT_TRUE(rev_deps == state.GetNode("out.o", 0));
+}
+
} // anonymous namespace
diff --git a/src/ninja.cc b/src/ninja.cc
index 1d94442..07b1f1e 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -306,15 +306,20 @@ Node* NinjaMain::CollectTarget(const char* cpath, string* err) {
if (node) {
if (first_dependent) {
if (node->out_edges().empty()) {
- *err = "'" + path + "' has no out edge";
- return NULL;
- }
- Edge* edge = node->out_edges()[0];
- if (edge->outputs_.empty()) {
- edge->Dump();
- Fatal("edge has no outputs");
+ Node* rev_deps = deps_log_.GetFirstReverseDepsNode(node);
+ if (!rev_deps) {
+ *err = "'" + path + "' has no out edge";
+ return NULL;
+ }
+ node = rev_deps;
+ } else {
+ Edge* edge = node->out_edges()[0];
+ if (edge->outputs_.empty()) {
+ edge->Dump();
+ Fatal("edge has no outputs");
+ }
+ node = edge->outputs_[0];
}
- node = edge->outputs_[0];
}
return node;
} else {