On unexpected output in a .d file, rebuild instead erroring.
authorNico Weber <nicolasweber@gmx.de>
Thu, 12 Mar 2015 16:06:50 +0000 (12:06 -0400)
committerNico Weber <nicolasweber@gmx.de>
Thu, 12 Mar 2015 16:06:50 +0000 (12:06 -0400)
Fixes #417.

src/build_test.cc
src/graph.cc

index 82da57b..65d189d 100644 (file)
@@ -2042,6 +2042,23 @@ TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
 }
 
+TEST_F(BuildTest, WrongOutputInDepfileCausesRebuild) {
+  string err;
+  const char* manifest =
+"rule cc\n"
+"  command = cc $in\n"
+"  depfile = $out.d\n"
+"build foo.o: cc foo.c\n";
+
+  fs_.Create("foo.c", "");
+  fs_.Create("foo.o", "");
+  fs_.Create("header.h", "");
+  fs_.Create("foo.o.d", "bar.o.d: header.h\n");
+
+  RebuildTarget("foo.o", manifest, "build_log", "ninja_deps");
+  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
+}
+
 TEST_F(BuildTest, Console) {
   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
 "rule console\n"
index cbf7921..76c4e9a 100644 (file)
@@ -390,12 +390,13 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path,
                         &depfile.out_.len_, &unused, err))
     return false;
 
-  // Check that this depfile matches the edge's output.
+  // Check that this depfile matches the edge's output, if not return false to
+  // mark the edge as dirty.
   Node* first_output = edge->outputs_[0];
   StringPiece opath = StringPiece(first_output->path());
   if (opath != depfile.out_) {
-    *err = "expected depfile '" + path + "' to mention '" +
-        first_output->path() + "', got '" + depfile.out_.AsString() + "'";
+    EXPLAIN("expected depfile '%s' to mention '%s', got '%s'", path.c_str(),
+            first_output->path().c_str(), depfile.out_.AsString().c_str());
     return false;
   }