From: Chris Hopman Date: Wed, 3 Jul 2013 21:26:25 +0000 (-0700) Subject: Fix restat dirty check logic for edges with multiple outputs X-Git-Tag: v1.4.0^2~22^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9635dae5558b2bb04f021699ed66b1f6f7634acd;p=platform%2Fupstream%2Fninja.git Fix restat dirty check logic for edges with multiple outputs In a normal dependency scan (see DependencyScan::RecomputeDirty) we mark all outputs of an Edge as dirty if any of the outputs is dirty. This is the correct behavior because if any output is dirty, we will run the command for that Edge and that can touch any of the outputs of the Edge and so all the outputs should be marked dirty. When updating the dirty state of Node's for a restat check, we were not applying this logic, instead only those outputs that were actually "dirty" were marked dirty. Before this patch, restat edges with multiple outputs caused not all dependent edges to run. --- diff --git a/src/build.cc b/src/build.cc index 2fbfdec..143aeb2 100644 --- a/src/build.cc +++ b/src/build.cc @@ -422,23 +422,22 @@ void Plan::CleanNode(DependencyScan* scan, Node* node) { } string command = (*ei)->EvaluateCommand(true); - // Now, recompute the dirty state of each output. - bool all_outputs_clean = true; + // Now, this edge is dirty if any of the outputs are dirty. + bool dirty = false; for (vector::iterator ni = (*ei)->outputs_.begin(); - ni != (*ei)->outputs_.end(); ++ni) { - if (!(*ni)->dirty()) - continue; + !dirty && ni != (*ei)->outputs_.end(); ++ni) { + dirty = scan->RecomputeOutputDirty(*ei, most_recent_input, 0, + command, *ni); + } - if (scan->RecomputeOutputDirty(*ei, most_recent_input, 0, - command, *ni)) { - all_outputs_clean = false; - } else { + // If the edge isn't dirty, clean the outputs and mark the edge as not + // wanted. + if (!dirty) { + for (vector::iterator ni = (*ei)->outputs_.begin(); + ni != (*ei)->outputs_.end(); ++ni) { CleanNode(scan, *ni); } - } - // If we cleaned all outputs, mark the edge as not wanted. - if (all_outputs_clean) { want_i->second = false; --wanted_edges_; if (!(*ei)->is_phony())