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) {
assert(!outputs_.empty());
for (vector<Node*>::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() ||