From bcc8ad1369ae3d90631729d29cc83c377f44535e Mon Sep 17 00:00:00 2001 From: Maxim Kalaev Date: Wed, 29 Aug 2012 22:25:44 +0200 Subject: [PATCH] safer build: consider target dirty if depfile is missing --- src/graph.cc | 12 +++++++++--- src/graph_test.cc | 25 +++++++++++++++++++++++++ 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()); +} -- 2.7.4