summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-09-14 00:32:15 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2011-09-14 02:01:12 (GMT)
commitf14039d44a93b7717e5335a371ea22fe4561aaf8 (patch)
treea888a3578c1d2eaf452d9f86273aa7cbadad136c
parent22c309760a5a38ccc88a6f700e101868236ce4ab (diff)
downloadNinja-f14039d44a93b7717e5335a371ea22fe4561aaf8.zip
Ninja-f14039d44a93b7717e5335a371ea22fe4561aaf8.tar.gz
Ninja-f14039d44a93b7717e5335a371ea22fe4561aaf8.tar.bz2
Consider missing phony targets with no dependencies out of date
Commit 639c8f0 ("don't mark phony edges dirty if none of their inputs are dirty") modified the behaviour of the "phony" built-in rule. Previously, when the output file was missing, it was marked as dirty. After 639c8f0, it was always marked as clean unless one of the dependencies was dirty. The depfile mechanism uses the old behaviour of "phony" to rebuild an object file if any of the headers were missing. Restore the old "phony" behaviour only for the case where the build statement has no dependencies. This is slightly inconsistent, but I can't really see any other use case for an alias of nothing. Also, document this behaviour.
-rw-r--r--doc/manual.asciidoc6
-rw-r--r--src/build_test.cc9
-rw-r--r--src/graph.cc5
3 files changed, 19 insertions, 1 deletions
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc
index 9506f0c..ed44bd2 100644
--- a/doc/manual.asciidoc
+++ b/doc/manual.asciidoc
@@ -277,6 +277,12 @@ nothing, but phony rules are handled specially in that they aren't
printed when run, logged (see below), nor do they contribute to the
command count printed as part of the build process.
+`phony' can also be used to create dummy targets for files which
+may not exist at build time. If a phony build statement is written
+without any dependencies, the target will be considered out of date if
+it does not exist. Without a phony build statement, Ninja will report
+an error if the file does not exist and is required by the build.
+
Default target statements
~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/build_test.cc b/src/build_test.cc
index 752a4b4..84359a3 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -533,6 +533,15 @@ TEST_F(BuildTest, OrderOnlyDeps) {
EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
EXPECT_EQ("", err);
EXPECT_TRUE(builder_.AlreadyUpToDate());
+
+ // implicit dep missing, expect rebuild.
+ fs_.RemoveFile("bar.h");
+ commands_ran_.clear();
+ state_.stat_cache_.Invalidate();
+ EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
+ EXPECT_TRUE(builder_.Build(&err));
+ ASSERT_EQ("", err);
+ ASSERT_EQ(1u, commands_ran_.size());
}
TEST_F(BuildTest, Phony) {
diff --git a/src/graph.cc b/src/graph.cc
index 5c37ac0..9c99b3d 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -77,9 +77,12 @@ bool Edge::RecomputeDirty(State* state, DiskInterface* disk_interface,
if (is_phony()) {
// Phony edges don't write any output.
- // They're only dirty if an input is dirty.
+ // They're only dirty if an input is dirty, or if there are no inputs
+ // and we're missing the output.
if (dirty)
(*i)->dirty_ = true;
+ else if (inputs_.empty() && !(*i)->file_->exists())
+ (*i)->dirty_ = true;
continue;
}