summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.cc26
-rw-r--r--src/build.h8
-rw-r--r--src/build_test.cc78
3 files changed, 75 insertions, 37 deletions
diff --git a/src/build.cc b/src/build.cc
index 90e910f..d76d7f2 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -377,7 +377,7 @@ void Plan::ScheduleWork(map<Edge*, Want>::iterator want_e) {
}
}
-void Plan::EdgeFinished(Edge* edge, EdgeResult result) {
+bool Plan::EdgeFinished(Edge* edge, EdgeResult result, string* err) {
map<Edge*, Want>::iterator e = want_.find(edge);
assert(e != want_.end());
bool directly_wanted = e->second != kWantNothing;
@@ -389,7 +389,7 @@ void Plan::EdgeFinished(Edge* edge, EdgeResult result) {
// The rest of this function only applies to successful commands.
if (result != kEdgeSucceeded)
- return;
+ return true;
if (directly_wanted)
--wanted_edges_;
@@ -399,11 +399,13 @@ void Plan::EdgeFinished(Edge* edge, EdgeResult result) {
// Check off any nodes we were waiting for with this edge.
for (vector<Node*>::iterator o = edge->outputs_.begin();
o != edge->outputs_.end(); ++o) {
- NodeFinished(*o);
+ if (!NodeFinished(*o, err))
+ return false;
}
+ return true;
}
-void Plan::NodeFinished(Node* node) {
+bool Plan::NodeFinished(Node* node, string* err) {
// See if we we want any edges from this node.
for (vector<Edge*>::const_iterator oe = node->out_edges().begin();
oe != node->out_edges().end(); ++oe) {
@@ -418,10 +420,12 @@ void Plan::NodeFinished(Node* node) {
} else {
// We do not need to build this edge, but we might need to build one of
// its dependents.
- EdgeFinished(*oe, kEdgeSucceeded);
+ if (!EdgeFinished(*oe, kEdgeSucceeded, err))
+ return false;
}
}
}
+ return true;
}
bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) {
@@ -661,7 +665,11 @@ bool Builder::Build(string* err) {
}
if (edge->is_phony()) {
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
+ Cleanup();
+ status_->BuildFinished();
+ return false;
+ }
} else {
++pending_commands;
}
@@ -781,8 +789,7 @@ bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
// The rest of this function only applies to successful commands.
if (!result->success()) {
- plan_.EdgeFinished(edge, Plan::kEdgeFailed);
- return true;
+ return plan_.EdgeFinished(edge, Plan::kEdgeFailed, err);
}
// Restat the edge outputs
@@ -838,7 +845,8 @@ bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
}
}
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err))
+ return false;
// Delete any left over response file.
string rspfile = edge->GetUnescapedRspfile();
diff --git a/src/build.h b/src/build.h
index a42b8d4..fdd9891 100644
--- a/src/build.h
+++ b/src/build.h
@@ -63,7 +63,8 @@ struct Plan {
};
/// Mark an edge as done building (whether it succeeded or failed).
- void EdgeFinished(Edge* edge, EdgeResult result);
+ /// Returns 'true'.
+ bool EdgeFinished(Edge* edge, EdgeResult result, string* err);
/// Clean the given node during the build.
/// Return false on error.
@@ -77,7 +78,10 @@ struct Plan {
private:
bool AddSubTarget(Node* node, Node* dependent, string* err);
- void NodeFinished(Node* node);
+
+ /// Update plan with knowledge that the given node is up to date.
+ /// Returns 'true'.
+ bool NodeFinished(Node* node, string* err);
/// Enumerate possible steps we want for an edge.
enum Want
diff --git a/src/build_test.cc b/src/build_test.cc
index 46ab33e..b50b66f 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -68,14 +68,16 @@ TEST_F(PlanTest, Basic) {
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
ASSERT_EQ("mid", edge->inputs_[0]->path());
ASSERT_EQ("out", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
ASSERT_FALSE(plan_.more_to_do());
edge = plan_.FindWork();
@@ -99,11 +101,13 @@ TEST_F(PlanTest, DoubleOutputDirect) {
Edge* edge;
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat in
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat mid1 mid2
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_FALSE(edge); // done
@@ -129,19 +133,23 @@ TEST_F(PlanTest, DoubleOutputIndirect) {
Edge* edge;
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat in
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat a1
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat a2
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat b1 b2
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_FALSE(edge); // done
@@ -167,19 +175,23 @@ TEST_F(PlanTest, DoubleDependent) {
Edge* edge;
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat in
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat mid
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat mid
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge); // cat a1 a2
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_FALSE(edge); // done
@@ -204,7 +216,8 @@ void PlanTest::TestPoolWithDepthOne(const char* test_case) {
// This will be false since poolcat is serialized
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
@@ -213,7 +226,8 @@ void PlanTest::TestPoolWithDepthOne(const char* test_case) {
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
ASSERT_FALSE(plan_.more_to_do());
edge = plan_.FindWork();
@@ -289,7 +303,8 @@ TEST_F(PlanTest, PoolsWithDepthTwo) {
ASSERT_EQ("outb3", edge->outputs_[0]->path());
// finish out1
- plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edges.pop_front();
// out3 should be available
@@ -300,19 +315,22 @@ TEST_F(PlanTest, PoolsWithDepthTwo) {
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(out3, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(out3, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
ASSERT_FALSE(plan_.FindWork());
for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
- plan_.EdgeFinished(*it, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(*it, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
}
Edge* last = plan_.FindWork();
ASSERT_TRUE(last);
ASSERT_EQ("allTheThings", last->outputs_[0]->path());
- plan_.EdgeFinished(last, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(last, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
ASSERT_FALSE(plan_.more_to_do());
ASSERT_FALSE(plan_.FindWork());
@@ -354,7 +372,8 @@ TEST_F(PlanTest, PoolWithRedundantEdges) {
edge = initial_edges[1]; // Foo first
ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
@@ -362,11 +381,13 @@ TEST_F(PlanTest, PoolWithRedundantEdges) {
ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = initial_edges[0]; // Now for bar
ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
@@ -374,7 +395,8 @@ TEST_F(PlanTest, PoolWithRedundantEdges) {
ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
@@ -382,14 +404,16 @@ TEST_F(PlanTest, PoolWithRedundantEdges) {
ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
ASSERT_FALSE(plan_.FindWork());
ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
ASSERT_EQ("all", edge->outputs_[0]->path());
- plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
+ plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_FALSE(edge);
@@ -422,7 +446,8 @@ TEST_F(PlanTest, PoolWithFailingEdge) {
// This will be false since poolcat is serialized
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(edge, Plan::kEdgeFailed);
+ plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
+ ASSERT_EQ("", err);
edge = plan_.FindWork();
ASSERT_TRUE(edge);
@@ -431,7 +456,8 @@ TEST_F(PlanTest, PoolWithFailingEdge) {
ASSERT_FALSE(plan_.FindWork());
- plan_.EdgeFinished(edge, Plan::kEdgeFailed);
+ plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
+ ASSERT_EQ("", err);
ASSERT_TRUE(plan_.more_to_do()); // Jobs have failed
edge = plan_.FindWork();