}
// Test case from
-// https://github.com/martine/ninja/issues/148
-// disabled right now because the build gets stuck (which is the bug).
-TEST_F(BuildTest, DISABLED_MultiOutIn) {
+// https://github.com/martine/ninja/issues/148
+TEST_F(BuildTest, MultiOutIn) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule touch\n"
" command = touch $out\n"
outputs_ready_ = true;
+ // Visit all inputs; we're dirty if any of the inputs are dirty.
time_t most_recent_input = 1;
for (vector<Node*>::iterator i = inputs_.begin(); i != inputs_.end(); ++i) {
if ((*i)->file_->StatIfNecessary(disk_interface)) {
}
}
- BuildLog* build_log = state ? state->build_log_ : 0;
- string command = EvaluateCommand();
+ // We may also be dirty due to output state: missing outputs, out of
+ // date outputs, etc. Visit all outputs and determine whether they're dirty.
+ if (!dirty) {
+ BuildLog* build_log = state ? state->build_log_ : 0;
+ string command = EvaluateCommand();
+
+ for (vector<Node*>::iterator i = outputs_.begin();
+ i != outputs_.end(); ++i) {
+ (*i)->file_->StatIfNecessary(disk_interface);
+ if (RecomputeOutputDirty(build_log, most_recent_input, command, *i)) {
+ dirty = true;
+ break;
+ }
+ }
+ }
- assert(!outputs_.empty());
+ // Finally, visit each output to mark off that we've visited it, and update
+ // their dirty state if necessary.
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 to mark that we've
- // visited their dependents.
(*i)->file_->StatIfNecessary(disk_interface);
- if (dirty || RecomputeOutputDirty(build_log, most_recent_input, command, *i)) {
+ if (dirty)
(*i)->dirty_ = true;
- outputs_ready_ = false;
- }
}
+ // 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)
+ outputs_ready_ = false;
+
return true;
}