From 639c8f0bad935625f3e61fb9dfac7da17b4d7625 Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Fri, 9 Sep 2011 13:48:27 -0700 Subject: [PATCH] don't mark phony edges dirty if none of their inputs are dirty Because the output file is always missing, we'd consider a phony edge dirty even when there wasn't any work to do. Most importantly, that would mean we wouldn't print "nothing to do" in the common case of everything being up to date when building an alias. --- src/build_test.cc | 18 ++++++++++++------ src/graph.cc | 13 +++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/build_test.cc b/src/build_test.cc index db69628..c8d338b 100644 --- a/src/build_test.cc +++ b/src/build_test.cc @@ -541,13 +541,19 @@ TEST_F(BuildTest, Phony) { EXPECT_TRUE(builder_.Build(&err)); ASSERT_EQ("", err); ASSERT_EQ(1u, commands_ran_.size()); +} + +TEST_F(BuildTest, PhonyNoWork) { + string err; + ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, +"build out: cat bar.cc\n" +"build all: phony out\n")); + fs_.Create("bar.cc", now_, ""); + fs_.Create("out", now_, ""); - // XXX need a test that asserts we do nothing when we only - // have pending phony rules. - // fs_.Create("out", now_, ""); - // EXPECT_TRUE(builder_.AddTarget("all", &err)); - // ASSERT_EQ("", err); - // EXPECT_TRUE(builder_.AlreadyUpToDate()); + EXPECT_TRUE(builder_.AddTarget("all", &err)); + ASSERT_EQ("", err); + EXPECT_TRUE(builder_.AlreadyUpToDate()); } TEST_F(BuildTest, Fail) { diff --git a/src/graph.cc b/src/graph.cc index 82716aa..c43cf70 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -70,10 +70,19 @@ bool Edge::RecomputeDirty(State* state, DiskInterface* disk_interface, assert(!outputs_.empty()); for (vector::iterator i = outputs_.begin(); i != outputs_.end(); ++i) { - // We may have other outputs, that our input-recursive traversal hasn't hit - // yet (or never will). Stat them if we haven't already. + // We may have other outputs that our input-recursive traversal hasn't hit + // yet (or never will). Stat them if we haven't already to mark that we've + // visited their dependents. (*i)->file_->StatIfNecessary(disk_interface); + if (is_phony()) { + // Phony edges don't write any output. + // They're only dirty if an input is dirty. + if (dirty) + (*i)->dirty_ = true; + continue; + } + // Output is dirty if we're dirty, we're missing the output, // or if it's older than the most recent input mtime. if (dirty || !(*i)->file_->exists() || -- 2.7.4