Ninja
graph.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "graph.h"
16 
17 #include <algorithm>
18 #include <deque>
19 #include <assert.h>
20 #include <stdio.h>
21 
22 #include "build_log.h"
23 #include "debug_flags.h"
24 #include "depfile_parser.h"
25 #include "deps_log.h"
26 #include "disk_interface.h"
27 #include "manifest_parser.h"
28 #include "metrics.h"
29 #include "state.h"
30 #include "util.h"
31 
32 using namespace std;
33 
34 bool Node::Stat(DiskInterface* disk_interface, string* err) {
35  mtime_ = disk_interface->Stat(path_, err);
36  if (mtime_ == -1) {
37  return false;
38  }
39  exists_ = (mtime_ != 0) ? ExistenceStatusExists : ExistenceStatusMissing;
40  return true;
41 }
42 
44  if (!exists()) {
45  mtime_ = std::max(mtime_, mtime);
46  }
47 }
48 
50  std::vector<Node*>* validation_nodes,
51  string* err) {
52  std::vector<Node*> stack;
53  std::vector<Node*> new_validation_nodes;
54 
55  std::deque<Node*> nodes(1, initial_node);
56 
57  // RecomputeNodeDirty might return new validation nodes that need to be
58  // checked for dirty state, keep a queue of nodes to visit.
59  while (!nodes.empty()) {
60  Node* node = nodes.front();
61  nodes.pop_front();
62 
63  stack.clear();
64  new_validation_nodes.clear();
65 
66  if (!RecomputeNodeDirty(node, &stack, &new_validation_nodes, err))
67  return false;
68  nodes.insert(nodes.end(), new_validation_nodes.begin(),
69  new_validation_nodes.end());
70  if (!new_validation_nodes.empty()) {
71  assert(validation_nodes &&
72  "validations require RecomputeDirty to be called with validation_nodes");
73  validation_nodes->insert(validation_nodes->end(),
74  new_validation_nodes.begin(),
75  new_validation_nodes.end());
76  }
77  }
78 
79  return true;
80 }
81 
82 bool DependencyScan::RecomputeNodeDirty(Node* node, std::vector<Node*>* stack,
83  std::vector<Node*>* validation_nodes,
84  string* err) {
85  Edge* edge = node->in_edge();
86  if (!edge) {
87  // If we already visited this leaf node then we are done.
88  if (node->status_known())
89  return true;
90  // This node has no in-edge; it is dirty if it is missing.
91  if (!node->StatIfNecessary(disk_interface_, err))
92  return false;
93  if (!node->exists())
94  explanations_.Record(node, "%s has no in-edge and is missing",
95  node->path().c_str());
96  node->set_dirty(!node->exists());
97  return true;
98  }
99 
100  // If we already finished this edge then we are done.
101  if (edge->mark_ == Edge::VisitDone)
102  return true;
103 
104  // If we encountered this edge earlier in the call stack we have a cycle.
105  if (!VerifyDAG(node, stack, err))
106  return false;
107 
108  // Mark the edge temporarily while in the call stack.
109  edge->mark_ = Edge::VisitInStack;
110  stack->push_back(node);
111 
112  bool dirty = false;
113  edge->outputs_ready_ = true;
114  edge->deps_missing_ = false;
115 
116  if (!edge->deps_loaded_) {
117  // This is our first encounter with this edge.
118  // If there is a pending dyndep file, visit it now:
119  // * If the dyndep file is ready then load it now to get any
120  // additional inputs and outputs for this and other edges.
121  // Once the dyndep file is loaded it will no longer be pending
122  // if any other edges encounter it, but they will already have
123  // been updated.
124  // * If the dyndep file is not ready then since is known to be an
125  // input to this edge, the edge will not be considered ready below.
126  // Later during the build the dyndep file will become ready and be
127  // loaded to update this edge before it can possibly be scheduled.
128  if (edge->dyndep_ && edge->dyndep_->dyndep_pending()) {
129  if (!RecomputeNodeDirty(edge->dyndep_, stack, validation_nodes, err))
130  return false;
131 
132  if (!edge->dyndep_->in_edge() ||
133  edge->dyndep_->in_edge()->outputs_ready()) {
134  // The dyndep file is ready, so load it now.
135  if (!LoadDyndeps(edge->dyndep_, err))
136  return false;
137  }
138  }
139  }
140 
141  // Load output mtimes so we can compare them to the most recent input below.
142  for (vector<Node*>::iterator o = edge->outputs_.begin();
143  o != edge->outputs_.end(); ++o) {
144  if (!(*o)->StatIfNecessary(disk_interface_, err))
145  return false;
146  }
147 
148  if (!edge->deps_loaded_) {
149  // This is our first encounter with this edge. Load discovered deps.
150  edge->deps_loaded_ = true;
151  if (!dep_loader_.LoadDeps(edge, err)) {
152  if (!err->empty())
153  return false;
154  // Failed to load dependency info: rebuild to regenerate it.
155  // LoadDeps() did explanations_->Record() already, no need to do it here.
156  dirty = edge->deps_missing_ = true;
157  }
158  }
159 
160  // Store any validation nodes from the edge for adding to the initial
161  // nodes. Don't recurse into them, that would trigger the dependency
162  // cycle detector if the validation node depends on this node.
163  // RecomputeDirty will add the validation nodes to the initial nodes
164  // and recurse into them.
165  validation_nodes->insert(validation_nodes->end(),
166  edge->validations_.begin(), edge->validations_.end());
167 
168  // Visit all inputs; we're dirty if any of the inputs are dirty.
169  Node* most_recent_input = NULL;
170  for (vector<Node*>::iterator i = edge->inputs_.begin();
171  i != edge->inputs_.end(); ++i) {
172  // Visit this input.
173  if (!RecomputeNodeDirty(*i, stack, validation_nodes, err))
174  return false;
175 
176  // If an input is not ready, neither are our outputs.
177  if (Edge* in_edge = (*i)->in_edge()) {
178  if (!in_edge->outputs_ready_)
179  edge->outputs_ready_ = false;
180  }
181 
182  if (!edge->is_order_only(i - edge->inputs_.begin())) {
183  // If a regular input is dirty (or missing), we're dirty.
184  // Otherwise consider mtime.
185  if ((*i)->dirty()) {
186  explanations_.Record(node, "%s is dirty", (*i)->path().c_str());
187  dirty = true;
188  } else {
189  if (!most_recent_input || (*i)->mtime() > most_recent_input->mtime()) {
190  most_recent_input = *i;
191  }
192  }
193  }
194  }
195 
196  // We may also be dirty due to output state: missing outputs, out of
197  // date outputs, etc. Visit all outputs and determine whether they're dirty.
198  if (!dirty)
199  if (!RecomputeOutputsDirty(edge, most_recent_input, &dirty, err))
200  return false;
201 
202  // Finally, visit each output and update their dirty state if necessary.
203  for (vector<Node*>::iterator o = edge->outputs_.begin();
204  o != edge->outputs_.end(); ++o) {
205  if (dirty)
206  (*o)->MarkDirty();
207  }
208 
209  // If an edge is dirty, its outputs are normally not ready. (It's
210  // possible to be clean but still not be ready in the presence of
211  // order-only inputs.)
212  // But phony edges with no inputs have nothing to do, so are always
213  // ready.
214  if (dirty && !(edge->is_phony() && edge->inputs_.empty()))
215  edge->outputs_ready_ = false;
216 
217  // Mark the edge as finished during this walk now that it will no longer
218  // be in the call stack.
219  edge->mark_ = Edge::VisitDone;
220  assert(stack->back() == node);
221  stack->pop_back();
222 
223  return true;
224 }
225 
226 bool DependencyScan::VerifyDAG(Node* node, vector<Node*>* stack, string* err) {
227  Edge* edge = node->in_edge();
228  assert(edge != NULL);
229 
230  // If we have no temporary mark on the edge then we do not yet have a cycle.
231  if (edge->mark_ != Edge::VisitInStack)
232  return true;
233 
234  // We have this edge earlier in the call stack. Find it.
235  vector<Node*>::iterator start = stack->begin();
236  while (start != stack->end() && (*start)->in_edge() != edge)
237  ++start;
238  assert(start != stack->end());
239 
240  // Make the cycle clear by reporting its start as the node at its end
241  // instead of some other output of the starting edge. For example,
242  // running 'ninja b' on
243  // build a b: cat c
244  // build c: cat a
245  // should report a -> c -> a instead of b -> c -> a.
246  *start = node;
247 
248  // Construct the error message rejecting the cycle.
249  *err = "dependency cycle: ";
250  for (vector<Node*>::const_iterator i = start; i != stack->end(); ++i) {
251  err->append((*i)->path());
252  err->append(" -> ");
253  }
254  err->append((*start)->path());
255 
256  if ((start + 1) == stack->end() && edge->maybe_phonycycle_diagnostic()) {
257  // The manifest parser would have filtered out the self-referencing
258  // input if it were not configured to allow the error.
259  err->append(" [-w phonycycle=err]");
260  }
261 
262  return false;
263 }
264 
265 bool DependencyScan::RecomputeOutputsDirty(Edge* edge, Node* most_recent_input,
266  bool* outputs_dirty, string* err) {
267  string command = edge->EvaluateCommand(/*incl_rsp_file=*/true);
268  for (vector<Node*>::iterator o = edge->outputs_.begin();
269  o != edge->outputs_.end(); ++o) {
270  if (RecomputeOutputDirty(edge, most_recent_input, command, *o)) {
271  *outputs_dirty = true;
272  return true;
273  }
274  }
275  return true;
276 }
277 
279  const Node* most_recent_input,
280  const string& command,
281  Node* output) {
282  if (edge->is_phony()) {
283  // Phony edges don't write any output. Outputs are only dirty if
284  // there are no inputs and we're missing the output.
285  if (edge->inputs_.empty() && !output->exists()) {
286  explanations_.Record(
287  output, "output %s of phony edge with no inputs doesn't exist",
288  output->path().c_str());
289  return true;
290  }
291 
292  // Update the mtime with the newest input. Dependents can thus call mtime()
293  // on the fake node and get the latest mtime of the dependencies
294  if (most_recent_input) {
295  output->UpdatePhonyMtime(most_recent_input->mtime());
296  }
297 
298  // Phony edges are clean, nothing to do
299  return false;
300  }
301 
302  // Dirty if we're missing the output.
303  if (!output->exists()) {
304  explanations_.Record(output, "output %s doesn't exist",
305  output->path().c_str());
306  return true;
307  }
308 
309  BuildLog::LogEntry* entry = 0;
310 
311  // If this is a restat rule, we may have cleaned the output in a
312  // previous run and stored the command start time in the build log.
313  // We don't want to consider a restat rule's outputs as dirty unless
314  // an input changed since the last run, so we'll skip checking the
315  // output file's actual mtime and simply check the recorded mtime from
316  // the log against the most recent input's mtime (see below)
317  bool used_restat = false;
318  if (edge->GetBindingBool("restat") && build_log() &&
319  (entry = build_log()->LookupByOutput(output->path()))) {
320  used_restat = true;
321  }
322 
323  // Dirty if the output is older than the input.
324  if (!used_restat && most_recent_input && output->mtime() < most_recent_input->mtime()) {
325  explanations_.Record(output,
326  "output %s older than most recent input %s "
327  "(%" PRId64 " vs %" PRId64 ")",
328  output->path().c_str(),
329  most_recent_input->path().c_str(), output->mtime(),
330  most_recent_input->mtime());
331  return true;
332  }
333 
334  if (build_log()) {
335  bool generator = edge->GetBindingBool("generator");
336  if (entry || (entry = build_log()->LookupByOutput(output->path()))) {
337  if (!generator &&
338  BuildLog::LogEntry::HashCommand(command) != entry->command_hash) {
339  // May also be dirty due to the command changing since the last build.
340  // But if this is a generator rule, the command changing does not make us
341  // dirty.
342  explanations_.Record(output, "command line changed for %s",
343  output->path().c_str());
344  return true;
345  }
346  if (most_recent_input && entry->mtime < most_recent_input->mtime()) {
347  // May also be dirty due to the mtime in the log being older than the
348  // mtime of the most recent input. This can occur even when the mtime
349  // on disk is newer if a previous run wrote to the output file but
350  // exited with an error or was interrupted. If this was a restat rule,
351  // then we only check the recorded mtime against the most recent input
352  // mtime and ignore the actual output's mtime above.
353  explanations_.Record(
354  output,
355  "recorded mtime of %s older than most recent input %s (%" PRId64
356  " vs %" PRId64 ")",
357  output->path().c_str(), most_recent_input->path().c_str(),
358  entry->mtime, most_recent_input->mtime());
359  return true;
360  }
361  }
362  if (!entry && !generator) {
363  explanations_.Record(output, "command line not found in log for %s",
364  output->path().c_str());
365  return true;
366  }
367  }
368 
369  return false;
370 }
371 
372 bool DependencyScan::LoadDyndeps(Node* node, string* err) const {
373  return dyndep_loader_.LoadDyndeps(node, err);
374 }
375 
377  string* err) const {
378  return dyndep_loader_.LoadDyndeps(node, ddf, err);
379 }
380 
381 bool Edge::AllInputsReady() const {
382  for (vector<Node*>::const_iterator i = inputs_.begin();
383  i != inputs_.end(); ++i) {
384  if ((*i)->in_edge() && !(*i)->in_edge()->outputs_ready())
385  return false;
386  }
387  return true;
388 }
389 
390 /// An Env for an Edge, providing $in and $out.
391 struct EdgeEnv : public Env {
392  enum EscapeKind { kShellEscape, kDoNotEscape };
393 
394  EdgeEnv(const Edge* const edge, const EscapeKind escape)
395  : edge_(edge), escape_in_out_(escape), recursive_(false) {}
396  virtual string LookupVariable(const string& var);
397 
398  /// Given a span of Nodes, construct a list of paths suitable for a command
399  /// line.
400  std::string MakePathList(const Node* const* span, size_t size, char sep) const;
401 
402  private:
403  std::vector<std::string> lookups_;
404  const Edge* const edge_;
407 };
408 
409 string EdgeEnv::LookupVariable(const string& var) {
410  if (var == "in" || var == "in_newline") {
411  int explicit_deps_count =
412  static_cast<int>(edge_->inputs_.size() - edge_->implicit_deps_ -
413  edge_->order_only_deps_);
414  return MakePathList(edge_->inputs_.data(), explicit_deps_count,
415  var == "in" ? ' ' : '\n');
416  } else if (var == "out") {
417  int explicit_outs_count =
418  static_cast<int>(edge_->outputs_.size() - edge_->implicit_outs_);
419  return MakePathList(&edge_->outputs_[0], explicit_outs_count, ' ');
420  }
421 
422  // Technical note about the lookups_ vector.
423  //
424  // This is used to detect cycles during recursive variable expansion
425  // which can be seen as a graph traversal problem. Consider the following
426  // example:
427  //
428  // rule something
429  // command = $foo $foo $var1
430  // var1 = $var2
431  // var2 = $var3
432  // var3 = $var1
433  // foo = FOO
434  //
435  // Each variable definition can be seen as a node in a graph that looks
436  // like the following:
437  //
438  // command --> foo
439  // |
440  // v
441  // var1 <-----.
442  // | |
443  // v |
444  // var2 ---> var3
445  //
446  // The lookups_ vector is used as a stack of visited nodes/variables
447  // during recursive expansion. Entering a node adds an item to the
448  // stack, leaving the node removes it.
449  //
450  // The recursive_ flag is used as a small performance optimization
451  // to never record the starting node in the stack when beginning a new
452  // expansion, since in most cases, expansions are not recursive
453  // at all.
454  //
455  if (recursive_) {
456  auto it = std::find(lookups_.begin(), lookups_.end(), var);
457  if (it != lookups_.end()) {
458  std::string cycle;
459  for (; it != lookups_.end(); ++it)
460  cycle.append(*it + " -> ");
461  cycle.append(var);
462  Fatal(("cycle in rule variables: " + cycle).c_str());
463  }
464  }
465 
466  // See notes on BindingEnv::LookupWithFallback.
467  const EvalString* eval = edge_->rule_->GetBinding(var);
468  bool record_varname = recursive_ && eval;
469  if (record_varname)
470  lookups_.push_back(var);
471 
472  // In practice, variables defined on rules never use another rule variable.
473  // For performance, only start checking for cycles after the first lookup.
474  recursive_ = true;
475  std::string result = edge_->env_->LookupWithFallback(var, eval, this);
476  if (record_varname)
477  lookups_.pop_back();
478  return result;
479 }
480 
481 std::string EdgeEnv::MakePathList(const Node* const* const span,
482  const size_t size, const char sep) const {
483  string result;
484  for (const Node* const* i = span; i != span + size; ++i) {
485  if (!result.empty())
486  result.push_back(sep);
487  const string& path = (*i)->PathDecanonicalized();
488  if (escape_in_out_ == kShellEscape) {
489 #ifdef _WIN32
490  GetWin32EscapedString(path, &result);
491 #else
492  GetShellEscapedString(path, &result);
493 #endif
494  } else {
495  result.append(path);
496  }
497  }
498  return result;
499 }
500 
501 std::string Edge::EvaluateCommand(const bool incl_rsp_file) const {
502  string command = GetBinding("command");
503  if (incl_rsp_file) {
504  string rspfile_content = GetBinding("rspfile_content");
505  if (!rspfile_content.empty())
506  command += ";rspfile=" + rspfile_content;
507  }
508  return command;
509 }
510 
511 std::string Edge::GetBinding(const std::string& key) const {
512  EdgeEnv env(this, EdgeEnv::kShellEscape);
513  return env.LookupVariable(key);
514 }
515 
516 bool Edge::GetBindingBool(const string& key) const {
517  return !GetBinding(key).empty();
518 }
519 
521  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
522  return env.LookupVariable("depfile");
523 }
524 
525 string Edge::GetUnescapedDyndep() const {
526  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
527  return env.LookupVariable("dyndep");
528 }
529 
530 std::string Edge::GetUnescapedRspfile() const {
531  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
532  return env.LookupVariable("rspfile");
533 }
534 
535 void Edge::Dump(const char* prefix) const {
536  printf("%s[ ", prefix);
537  for (vector<Node*>::const_iterator i = inputs_.begin();
538  i != inputs_.end() && *i != NULL; ++i) {
539  printf("%s ", (*i)->path().c_str());
540  }
541  printf("--%s-> ", rule_->name().c_str());
542  for (vector<Node*>::const_iterator i = outputs_.begin();
543  i != outputs_.end() && *i != NULL; ++i) {
544  printf("%s ", (*i)->path().c_str());
545  }
546  if (!validations_.empty()) {
547  printf(" validations ");
548  for (std::vector<Node*>::const_iterator i = validations_.begin();
549  i != validations_.end() && *i != NULL; ++i) {
550  printf("%s ", (*i)->path().c_str());
551  }
552  }
553  if (pool_) {
554  if (!pool_->name().empty()) {
555  printf("(in pool '%s')", pool_->name().c_str());
556  }
557  } else {
558  printf("(null pool?)");
559  }
560  printf("] 0x%p\n", this);
561 }
562 
563 bool Edge::is_phony() const {
564  return rule_->IsPhony();
565 }
566 
567 bool Edge::use_console() const {
568  return pool() == &State::kConsolePool;
569 }
570 
572  // CMake 2.8.12.x and 3.0.x produced self-referencing phony rules
573  // of the form "build a: phony ... a ...". Restrict our
574  // "phonycycle" diagnostic option to the form it used.
575  return is_phony() && outputs_.size() == 1 && implicit_outs_ == 0 &&
576  implicit_deps_ == 0;
577 }
578 
579 // static
580 string Node::PathDecanonicalized(const string& path, uint64_t slash_bits) {
581  string result = path;
582 #ifdef _WIN32
583  uint64_t mask = 1;
584  for (char* c = &result[0]; (c = strchr(c, '/')) != NULL;) {
585  if (slash_bits & mask)
586  *c = '\\';
587  c++;
588  mask <<= 1;
589  }
590 #endif
591  return result;
592 }
593 
594 void Node::Dump(const char* prefix) const {
595  printf("%s <%s 0x%p> mtime: %" PRId64 "%s, (:%s), ",
596  prefix, path().c_str(), this,
597  mtime(), exists() ? "" : " (:missing)",
598  dirty() ? " dirty" : " clean");
599  if (in_edge()) {
600  in_edge()->Dump("in-edge: ");
601  } else {
602  printf("no in-edge\n");
603  }
604  printf(" out edges:\n");
605  for (vector<Edge*>::const_iterator e = out_edges().begin();
606  e != out_edges().end() && *e != NULL; ++e) {
607  (*e)->Dump(" +- ");
608  }
609  if (!validation_out_edges().empty()) {
610  printf(" validation out edges:\n");
611  for (std::vector<Edge*>::const_iterator e = validation_out_edges().begin();
612  e != validation_out_edges().end() && *e != NULL; ++e) {
613  (*e)->Dump(" +- ");
614  }
615  }
616 }
617 
618 bool ImplicitDepLoader::LoadDeps(Edge* edge, string* err) {
619  string deps_type = edge->GetBinding("deps");
620  if (!deps_type.empty())
621  return LoadDepsFromLog(edge, err);
622 
623  string depfile = edge->GetUnescapedDepfile();
624  if (!depfile.empty())
625  return LoadDepFile(edge, depfile, err);
626 
627  // No deps to load.
628  return true;
629 }
630 
631 struct matches {
632  explicit matches(std::vector<StringPiece>::iterator i) : i_(i) {}
633 
634  bool operator()(const Node* node) const {
635  StringPiece opath = StringPiece(node->path());
636  return *i_ == opath;
637  }
638 
639  std::vector<StringPiece>::iterator i_;
640 };
641 
642 bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path,
643  string* err) {
644  METRIC_RECORD("depfile load");
645  // Read depfile content. Treat a missing depfile as empty.
646  string content;
647  switch (disk_interface_->ReadFile(path, &content, err)) {
648  case DiskInterface::Okay:
649  break;
651  err->clear();
652  break;
654  *err = "loading '" + path + "': " + *err;
655  return false;
656  }
657  // On a missing depfile: return false and empty *err.
658  Node* first_output = edge->outputs_[0];
659  if (content.empty()) {
660  explanations_.Record(first_output, "depfile '%s' is missing", path.c_str());
661  return false;
662  }
663 
664  DepfileParser depfile(depfile_parser_options_
665  ? *depfile_parser_options_
667  string depfile_err;
668  if (!depfile.Parse(&content, &depfile_err)) {
669  *err = path + ": " + depfile_err;
670  return false;
671  }
672 
673  if (depfile.outs_.empty()) {
674  *err = path + ": no outputs declared";
675  return false;
676  }
677 
678  uint64_t unused;
679  std::vector<StringPiece>::iterator primary_out = depfile.outs_.begin();
680  CanonicalizePath(const_cast<char*>(primary_out->str_), &primary_out->len_,
681  &unused);
682 
683  // Check that this depfile matches the edge's output, if not return false to
684  // mark the edge as dirty.
685  StringPiece opath = StringPiece(first_output->path());
686  if (opath != *primary_out) {
687  explanations_.Record(first_output,
688  "expected depfile '%s' to mention '%s', got '%s'",
689  path.c_str(), first_output->path().c_str(),
690  primary_out->AsString().c_str());
691  return false;
692  }
693 
694  // Ensure that all mentioned outputs are outputs of the edge.
695  for (std::vector<StringPiece>::iterator o = depfile.outs_.begin();
696  o != depfile.outs_.end(); ++o) {
697  matches m(o);
698  if (std::find_if(edge->outputs_.begin(), edge->outputs_.end(), m) == edge->outputs_.end()) {
699  *err = path + ": depfile mentions '" + o->AsString() + "' as an output, but no such output was declared";
700  return false;
701  }
702  }
703 
704  return ProcessDepfileDeps(edge, &depfile.ins_, err);
705 }
706 
708  Edge* edge, std::vector<StringPiece>* depfile_ins, std::string* err) {
709  // Preallocate space in edge->inputs_ to be filled in below.
710  vector<Node*>::iterator implicit_dep =
711  PreallocateSpace(edge, static_cast<int>(depfile_ins->size()));
712 
713  // Add all its in-edges.
714  for (std::vector<StringPiece>::iterator i = depfile_ins->begin();
715  i != depfile_ins->end(); ++i, ++implicit_dep) {
716  uint64_t slash_bits;
717  CanonicalizePath(const_cast<char*>(i->str_), &i->len_, &slash_bits);
718  Node* node = state_->GetNode(*i, slash_bits);
719  *implicit_dep = node;
720  node->AddOutEdge(edge);
721  }
722 
723  return true;
724 }
725 
726 bool ImplicitDepLoader::LoadDepsFromLog(Edge* edge, string* err) {
727  // NOTE: deps are only supported for single-target edges.
728  Node* output = edge->outputs_[0];
729  DepsLog::Deps* deps = deps_log_ ? deps_log_->GetDeps(output) : NULL;
730  if (!deps) {
731  explanations_.Record(output, "deps for '%s' are missing",
732  output->path().c_str());
733  return false;
734  }
735 
736  // Deps are invalid if the output is newer than the deps.
737  if (output->mtime() > deps->mtime) {
738  explanations_.Record(output,
739  "stored deps info out of date for '%s' (%" PRId64
740  " vs %" PRId64 ")",
741  output->path().c_str(), deps->mtime, output->mtime());
742  return false;
743  }
744 
745  Node** nodes = deps->nodes;
746  size_t node_count = deps->node_count;
747  edge->inputs_.insert(edge->inputs_.end() - edge->order_only_deps_,
748  nodes, nodes + node_count);
749  edge->implicit_deps_ += node_count;
750  for (size_t i = 0; i < node_count; ++i) {
751  nodes[i]->AddOutEdge(edge);
752  }
753  return true;
754 }
755 
756 vector<Node*>::iterator ImplicitDepLoader::PreallocateSpace(Edge* edge,
757  int count) {
758  edge->inputs_.insert(edge->inputs_.end() - edge->order_only_deps_,
759  (size_t)count, 0);
760  edge->implicit_deps_ += count;
761  return edge->inputs_.end() - edge->order_only_deps_ - count;
762 }
763 
764 void InputsCollector::VisitNode(const Node* node) {
765  const Edge* edge = node->in_edge();
766 
767  if (!edge) // A source file.
768  return;
769 
770  // Add inputs of the producing edge to the result,
771  // except if they are themselves produced by a phony
772  // edge.
773  for (const Node* input : edge->inputs_) {
774  if (!visited_nodes_.insert(input).second)
775  continue;
776 
777  VisitNode(input);
778 
779  const Edge* input_edge = input->in_edge();
780  if (!(input_edge && input_edge->is_phony())) {
781  inputs_.push_back(input);
782  }
783  }
784 }
785 
786 std::vector<std::string> InputsCollector::GetInputsAsStrings(
787  bool shell_escape) const {
788  std::vector<std::string> result;
789  result.reserve(inputs_.size());
790 
791  for (const Node* input : inputs_) {
792  std::string unescaped = input->PathDecanonicalized();
793  if (shell_escape) {
794  std::string path;
795 #ifdef _WIN32
796  GetWin32EscapedString(unescaped, &path);
797 #else
798  GetShellEscapedString(unescaped, &path);
799 #endif
800  result.push_back(std::move(path));
801  } else {
802  result.push_back(std::move(unescaped));
803  }
804  }
805  return result;
806 }
#define METRIC_RECORD(name)
The primary interface to metrics.
Definition: metrics.h:83
Definition: hash_map.h:26
TimeStamp mtime
Definition: build_log.h:65
uint64_t command_hash
Definition: build_log.h:62
static uint64_t HashCommand(StringPiece command)
Definition: build_log.cc:60
bool RecomputeOutputDirty(const Edge *edge, const Node *most_recent_input, const std::string &command, Node *output)
Recompute whether a given single output should be marked dirty.
Definition: graph.cc:278
bool RecomputeNodeDirty(Node *node, std::vector< Node * > *stack, std::vector< Node * > *validation_nodes, std::string *err)
Definition: graph.cc:82
bool VerifyDAG(Node *node, std::vector< Node * > *stack, std::string *err)
Definition: graph.cc:226
bool RecomputeOutputsDirty(Edge *edge, Node *most_recent_input, bool *dirty, std::string *err)
Recompute whether any output of the edge is dirty, if so sets |*dirty|.
Definition: graph.cc:265
bool LoadDyndeps(Node *node, std::string *err) const
Load a dyndep file from the given node's path and update the build graph with the new information.
bool RecomputeDirty(Node *node, std::vector< Node * > *validation_nodes, std::string *err)
Update the |dirty_| state of the given nodes by transitively inspecting their input edges.
Definition: graph.cc:49
Parser for the dependency information emitted by gcc's -M flags.
bool Parse(std::string *content, std::string *err)
Parse an input file.
std::vector< StringPiece > outs_
std::vector< StringPiece > ins_
TimeStamp mtime
Definition: deps_log.h:84
Node ** nodes
Definition: deps_log.h:86
int node_count
Definition: deps_log.h:85
Interface for accessing the disk.
virtual TimeStamp Stat(const std::string &path, std::string *err) const =0
stat() a file, returning the mtime, or 0 if missing and -1 on other errors.
Store data loaded from one dyndep file.
Definition: dyndep.h:42
An Env for an Edge, providing $in and $out.
Definition: graph.cc:391
std::string MakePathList(const Node *const *span, size_t size, char sep) const
Given a span of Nodes, construct a list of paths suitable for a command line.
Definition: graph.cc:481
std::vector< std::string > lookups_
Definition: graph.cc:403
const Edge *const edge_
Definition: graph.cc:404
virtual string LookupVariable(const string &var)
Definition: graph.cc:409
bool recursive_
Definition: graph.cc:406
EscapeKind escape_in_out_
Definition: graph.cc:405
EscapeKind
Definition: graph.cc:392
@ kShellEscape
Definition: graph.cc:392
@ kDoNotEscape
Definition: graph.cc:392
EdgeEnv(const Edge *const edge, const EscapeKind escape)
Definition: graph.cc:394
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:175
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
Definition: graph.cc:511
bool maybe_phonycycle_diagnostic() const
Definition: graph.cc:571
std::string GetUnescapedDyndep() const
Like GetBinding("dyndep"), but without shell escaping.
Definition: graph.cc:525
std::vector< Node * > outputs_
Definition: graph.h:217
VisitMark mark_
Definition: graph.h:221
bool outputs_ready() const
Definition: graph.h:233
int implicit_deps_
Definition: graph.h:243
Node * dyndep_
Definition: graph.h:219
bool is_order_only(size_t index)
Definition: graph.h:249
@ VisitInStack
Definition: graph.h:178
@ VisitDone
Definition: graph.h:179
int order_only_deps_
Definition: graph.h:244
bool is_phony() const
Definition: graph.cc:563
bool GetBindingBool(const std::string &key) const
Definition: graph.cc:516
bool deps_loaded_
Definition: graph.h:225
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
Definition: graph.cc:501
void Dump(const char *prefix="") const
Definition: graph.cc:535
bool use_console() const
Definition: graph.cc:567
std::vector< Node * > validations_
Definition: graph.h:218
std::vector< Node * > inputs_
Definition: graph.h:216
bool deps_missing_
Definition: graph.h:226
std::string GetUnescapedRspfile() const
Like GetBinding("rspfile"), but without shell escaping.
Definition: graph.cc:530
std::string GetUnescapedDepfile() const
Like GetBinding("depfile"), but without shell escaping.
Definition: graph.cc:520
bool AllInputsReady() const
Return true if all inputs' in-edges are ready.
Definition: graph.cc:381
bool outputs_ready_
Definition: graph.h:224
An interface for a scope for variable (e.g. "$foo") lookups.
Definition: eval_env.h:28
A tokenized string that contains variable references.
Definition: eval_env.h:35
bool LoadDepFile(Edge *edge, const std::string &path, std::string *err)
Load implicit dependencies for edge from a depfile attribute.
Definition: graph.cc:642
std::vector< Node * >::iterator PreallocateSpace(Edge *edge, int count)
Preallocate count spaces in the input array on edge, returning an iterator pointing at the first new ...
Definition: graph.cc:756
virtual bool ProcessDepfileDeps(Edge *edge, std::vector< StringPiece > *depfile_ins, std::string *err)
Process loaded implicit dependencies for edge and update the graph.
Definition: graph.cc:707
bool LoadDeps(Edge *edge, std::string *err)
Load implicit dependencies for edge.
Definition: graph.cc:618
bool LoadDepsFromLog(Edge *edge, std::string *err)
Load implicit dependencies for edge from the DepsLog.
Definition: graph.cc:726
void VisitNode(const Node *node)
Visit a single.
Definition: graph.cc:764
std::vector< std::string > GetInputsAsStrings(bool shell_escape=false) const
Same as inputs(), but returns the list of visited nodes as a list of strings, with optional shell esc...
Definition: graph.cc:786
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
Definition: graph.h:42
void set_dirty(bool dirty)
Definition: graph.h:94
void UpdatePhonyMtime(TimeStamp mtime)
If the file doesn't exist, set the mtime_ from its dependencies.
Definition: graph.cc:43
void Dump(const char *prefix="") const
Definition: graph.cc:594
void AddOutEdge(Edge *edge)
Definition: graph.h:116
const std::string & path() const
Definition: graph.h:82
Edge * in_edge() const
Definition: graph.h:100
bool status_known() const
Definition: graph.h:78
bool dyndep_pending() const
Definition: graph.h:97
bool exists() const
Definition: graph.h:74
void MarkDirty()
Definition: graph.h:95
std::string PathDecanonicalized() const
Get |path()| but use slash_bits to convert back to original slash styles.
Definition: graph.h:84
TimeStamp mtime() const
Definition: graph.h:91
bool StatIfNecessary(DiskInterface *disk_interface, std::string *err)
Return false on error.
Definition: graph.h:53
bool Stat(DiskInterface *disk_interface, std::string *err)
Return false on error.
Definition: graph.cc:34
static Pool kConsolePool
Definition: state.h:97
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:25
std::vector< StringPiece >::iterator i_
Definition: graph.cc:639
bool operator()(const Node *node) const
Definition: graph.cc:634
matches(std::vector< StringPiece >::iterator i)
Definition: graph.cc:632
int64_t TimeStamp
Definition: timestamp.h:31
void GetWin32EscapedString(const string &input, string *result)
Definition: util.cc:380
void GetShellEscapedString(const string &input, string *result)
Definition: util.cc:353
void CanonicalizePath(string *path, uint64_t *slash_bits)
Definition: util.cc:124
void Fatal(const char *msg,...)
Log a fatal message and exit.
Definition: util.cc:67
unsigned long long uint64_t
Definition: win32port.h:29
#define PRId64
Definition: win32port.h:33