summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Kalaev <maximk@il.ibm.com>2012-08-29 20:25:44 (GMT)
committerMaxim Kalaev <maximk@il.ibm.com>2012-08-30 17:53:51 (GMT)
commitbcc8ad1369ae3d90631729d29cc83c377f44535e (patch)
treeb32e35f170b93a57610fac6770bc426a723f7726
parent433b9d4e166544c52a494da2c810821fb39ab174 (diff)
downloadNinja-bcc8ad1369ae3d90631729d29cc83c377f44535e.zip
Ninja-bcc8ad1369ae3d90631729d29cc83c377f44535e.tar.gz
Ninja-bcc8ad1369ae3d90631729d29cc83c377f44535e.tar.bz2
safer build: consider target dirty if depfile is missing
-rw-r--r--src/graph.cc12
-rw-r--r--src/graph_test.cc25
2 files changed, 34 insertions, 3 deletions
diff --git a/src/graph.cc b/src/graph.cc
index 9654c1a..3567bfa 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -38,8 +38,13 @@ bool Edge::RecomputeDirty(State* state, DiskInterface* disk_interface,
outputs_ready_ = true;
if (!rule_->depfile().empty()) {
- if (!LoadDepFile(state, disk_interface, err))
- return false;
+ if (!LoadDepFile(state, disk_interface, err)) {
+ if (!err->empty())
+ return false;
+ EXPLAIN("Edge targets are dirty because depfile '%s' is missing",
+ EvaluateDepFile().c_str());
+ dirty = true;
+ }
}
// Visit all inputs; we're dirty if any of the inputs are dirty.
@@ -274,8 +279,9 @@ bool Edge::LoadDepFile(State* state, DiskInterface* disk_interface,
string content = disk_interface->ReadFile(path, err);
if (!err->empty())
return false;
+ // On a missing depfile: return false and empty *err.
if (content.empty())
- return true;
+ return false;
DepfileParser depfile;
string depfile_err;
diff --git a/src/graph_test.cc b/src/graph_test.cc
index 38ff28a..4b41f8a 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -159,3 +159,28 @@ TEST_F(GraphTest, DepfileWithCanonicalizablePath) {
EXPECT_FALSE(GetNode("out.o")->dirty());
}
+
+// Regression test for https://github.com/martine/ninja/issues/404
+TEST_F(GraphTest, DepfileRemoved) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"rule catdep\n"
+" depfile = $out.d\n"
+" command = cat $in > $out\n"
+"build ./out.o: catdep ./foo.cc\n"));
+ fs_.Create("foo.h", 1, "");
+ fs_.Create("foo.cc", 1, "");
+ fs_.Create("out.o.d", 2, "out.o: foo.h\n");
+ fs_.Create("out.o", 2, "");
+
+ Edge* edge = GetNode("out.o")->in_edge();
+ string err;
+ EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
+ ASSERT_EQ("", err);
+ EXPECT_FALSE(GetNode("out.o")->dirty());
+
+ state_.Reset();
+ fs_.RemoveFile("out.o.d");
+ EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
+ ASSERT_EQ("", err);
+ EXPECT_TRUE(GetNode("out.o")->dirty());
+}