summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2012-03-05 01:35:44 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2012-03-05 01:53:54 (GMT)
commitb70b3ad28279e9d8a56d3f52c2057978a81f65f1 (patch)
tree0c9f76d9e1fdf3cdbedc0ad0a45b863bfc064583 /src
parent2338d9340bb2c13746805b4b878c889008850962 (diff)
downloadNinja-b70b3ad28279e9d8a56d3f52c2057978a81f65f1.zip
Ninja-b70b3ad28279e9d8a56d3f52c2057978a81f65f1.tar.gz
Ninja-b70b3ad28279e9d8a56d3f52c2057978a81f65f1.tar.bz2
Mark a phony target with no inputs as outputs-ready
Even if such a target is dirty (i.e. the file does not exist), it has nothing to do, which makes it safe to mark as outputs-ready. Without this change, ninja will print no output when rebuilding the target (or an order-only dependency thereof), instead of reporting it has "no work to do".
Diffstat (limited to 'src')
-rw-r--r--src/build_test.cc26
-rw-r--r--src/graph.cc8
2 files changed, 30 insertions, 4 deletions
diff --git a/src/build_test.cc b/src/build_test.cc
index ca74ab6..5b35513 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -996,3 +996,29 @@ TEST_F(BuildTest, InterruptCleanup) {
builder_.Cleanup();
EXPECT_EQ(0, fs_.Stat("out2"));
}
+
+TEST_F(BuildTest, PhonyWithNoInputs) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"build nonexistent: phony\n"
+"build out1: cat || nonexistent\n"
+"build out2: cat nonexistent\n"));
+ fs_.Create("out1", now_, "");
+ fs_.Create("out2", now_, "");
+
+ // out1 should be up to date even though its input is dirty, because its
+ // order-only dependency has nothing to do.
+ string err;
+ EXPECT_TRUE(builder_.AddTarget("out1", &err));
+ ASSERT_EQ("", err);
+ EXPECT_TRUE(builder_.AlreadyUpToDate());
+
+ // out2 should still be out of date though, because its input is dirty.
+ err.clear();
+ commands_ran_.clear();
+ state_.Reset();
+ EXPECT_TRUE(builder_.AddTarget("out2", &err));
+ ASSERT_EQ("", err);
+ EXPECT_TRUE(builder_.Build(&err));
+ EXPECT_EQ("", err);
+ ASSERT_EQ(1u, commands_ran_.size());
+}
diff --git a/src/graph.cc b/src/graph.cc
index e2f966c..9d45ce1 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -96,10 +96,10 @@ bool Edge::RecomputeDirty(State* state, DiskInterface* disk_interface,
(*i)->MarkDirty();
}
- // If we're dirty, our outputs are not ready. (It's possible to be
- // clean but still have not be ready in the presence of order-only
- // inputs.)
- if (dirty)
+ // If we're dirty, our outputs are normally not ready. (It's possible to be
+ // clean but still not be ready in the presence of order-only inputs.)
+ // But phony edges with no inputs have nothing to do, so are always ready.
+ if (dirty && !(is_phony() && inputs_.empty()))
outputs_ready_ = false;
return true;