Coverage Report

Created: 2023-06-07 06:44

/src/ninja/src/graph.cc
Line
Count
Source (jump to first uncovered line)
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
0
bool Node::Stat(DiskInterface* disk_interface, string* err) {
35
0
  METRIC_RECORD("node stat");
36
0
  mtime_ = disk_interface->Stat(path_, err);
37
0
  if (mtime_ == -1) {
38
0
    return false;
39
0
  }
40
0
  exists_ = (mtime_ != 0) ? ExistenceStatusExists : ExistenceStatusMissing;
41
0
  return true;
42
0
}
43
44
0
void Node::UpdatePhonyMtime(TimeStamp mtime) {
45
0
  if (!exists()) {
46
0
    mtime_ = std::max(mtime_, mtime);
47
0
  }
48
0
}
49
50
bool DependencyScan::RecomputeDirty(Node* initial_node,
51
                                    std::vector<Node*>* validation_nodes,
52
0
                                    string* err) {
53
0
  std::vector<Node*> stack;
54
0
  std::vector<Node*> new_validation_nodes;
55
56
0
  std::deque<Node*> nodes(1, initial_node);
57
58
  // RecomputeNodeDirty might return new validation nodes that need to be
59
  // checked for dirty state, keep a queue of nodes to visit.
60
0
  while (!nodes.empty()) {
61
0
    Node* node = nodes.front();
62
0
    nodes.pop_front();
63
64
0
    stack.clear();
65
0
    new_validation_nodes.clear();
66
67
0
    if (!RecomputeNodeDirty(node, &stack, &new_validation_nodes, err))
68
0
      return false;
69
0
    nodes.insert(nodes.end(), new_validation_nodes.begin(),
70
0
                              new_validation_nodes.end());
71
0
    if (!new_validation_nodes.empty()) {
72
0
      assert(validation_nodes &&
73
0
          "validations require RecomputeDirty to be called with validation_nodes");
74
0
      validation_nodes->insert(validation_nodes->end(),
75
0
                           new_validation_nodes.begin(),
76
0
                           new_validation_nodes.end());
77
0
    }
78
0
  }
79
80
0
  return true;
81
0
}
82
83
bool DependencyScan::RecomputeNodeDirty(Node* node, std::vector<Node*>* stack,
84
                                        std::vector<Node*>* validation_nodes,
85
0
                                        string* err) {
86
0
  Edge* edge = node->in_edge();
87
0
  if (!edge) {
88
    // If we already visited this leaf node then we are done.
89
0
    if (node->status_known())
90
0
      return true;
91
    // This node has no in-edge; it is dirty if it is missing.
92
0
    if (!node->StatIfNecessary(disk_interface_, err))
93
0
      return false;
94
0
    if (!node->exists())
95
0
      EXPLAIN("%s has no in-edge and is missing", node->path().c_str());
96
0
    node->set_dirty(!node->exists());
97
0
    return true;
98
0
  }
99
100
  // If we already finished this edge then we are done.
101
0
  if (edge->mark_ == Edge::VisitDone)
102
0
    return true;
103
104
  // If we encountered this edge earlier in the call stack we have a cycle.
105
0
  if (!VerifyDAG(node, stack, err))
106
0
    return false;
107
108
  // Mark the edge temporarily while in the call stack.
109
0
  edge->mark_ = Edge::VisitInStack;
110
0
  stack->push_back(node);
111
112
0
  bool dirty = false;
113
0
  edge->outputs_ready_ = true;
114
0
  edge->deps_missing_ = false;
115
116
0
  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
0
    if (edge->dyndep_ && edge->dyndep_->dyndep_pending()) {
129
0
      if (!RecomputeNodeDirty(edge->dyndep_, stack, validation_nodes, err))
130
0
        return false;
131
132
0
      if (!edge->dyndep_->in_edge() ||
133
0
          edge->dyndep_->in_edge()->outputs_ready()) {
134
        // The dyndep file is ready, so load it now.
135
0
        if (!LoadDyndeps(edge->dyndep_, err))
136
0
          return false;
137
0
      }
138
0
    }
139
0
  }
140
141
  // Load output mtimes so we can compare them to the most recent input below.
142
0
  for (vector<Node*>::iterator o = edge->outputs_.begin();
143
0
       o != edge->outputs_.end(); ++o) {
144
0
    if (!(*o)->StatIfNecessary(disk_interface_, err))
145
0
      return false;
146
0
  }
147
148
0
  if (!edge->deps_loaded_) {
149
    // This is our first encounter with this edge.  Load discovered deps.
150
0
    edge->deps_loaded_ = true;
151
0
    if (!dep_loader_.LoadDeps(edge, err)) {
152
0
      if (!err->empty())
153
0
        return false;
154
      // Failed to load dependency info: rebuild to regenerate it.
155
      // LoadDeps() did EXPLAIN() already, no need to do it here.
156
0
      dirty = edge->deps_missing_ = true;
157
0
    }
158
0
  }
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
0
  validation_nodes->insert(validation_nodes->end(),
166
0
      edge->validations_.begin(), edge->validations_.end());
167
168
  // Visit all inputs; we're dirty if any of the inputs are dirty.
169
0
  Node* most_recent_input = NULL;
170
0
  for (vector<Node*>::iterator i = edge->inputs_.begin();
171
0
       i != edge->inputs_.end(); ++i) {
172
    // Visit this input.
173
0
    if (!RecomputeNodeDirty(*i, stack, validation_nodes, err))
174
0
      return false;
175
176
    // If an input is not ready, neither are our outputs.
177
0
    if (Edge* in_edge = (*i)->in_edge()) {
178
0
      if (!in_edge->outputs_ready_)
179
0
        edge->outputs_ready_ = false;
180
0
    }
181
182
0
    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
0
      if ((*i)->dirty()) {
186
0
        EXPLAIN("%s is dirty", (*i)->path().c_str());
187
0
        dirty = true;
188
0
      } else {
189
0
        if (!most_recent_input || (*i)->mtime() > most_recent_input->mtime()) {
190
0
          most_recent_input = *i;
191
0
        }
192
0
      }
193
0
    }
194
0
  }
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
0
  if (!dirty)
199
0
    if (!RecomputeOutputsDirty(edge, most_recent_input, &dirty, err))
200
0
      return false;
201
202
  // Finally, visit each output and update their dirty state if necessary.
203
0
  for (vector<Node*>::iterator o = edge->outputs_.begin();
204
0
       o != edge->outputs_.end(); ++o) {
205
0
    if (dirty)
206
0
      (*o)->MarkDirty();
207
0
  }
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
0
  if (dirty && !(edge->is_phony() && edge->inputs_.empty()))
215
0
    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
0
  edge->mark_ = Edge::VisitDone;
220
0
  assert(stack->back() == node);
221
0
  stack->pop_back();
222
223
0
  return true;
224
0
}
225
226
0
bool DependencyScan::VerifyDAG(Node* node, vector<Node*>* stack, string* err) {
227
0
  Edge* edge = node->in_edge();
228
0
  assert(edge != NULL);
229
230
  // If we have no temporary mark on the edge then we do not yet have a cycle.
231
0
  if (edge->mark_ != Edge::VisitInStack)
232
0
    return true;
233
234
  // We have this edge earlier in the call stack.  Find it.
235
0
  vector<Node*>::iterator start = stack->begin();
236
0
  while (start != stack->end() && (*start)->in_edge() != edge)
237
0
    ++start;
238
0
  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
0
  *start = node;
247
248
  // Construct the error message rejecting the cycle.
249
0
  *err = "dependency cycle: ";
250
0
  for (vector<Node*>::const_iterator i = start; i != stack->end(); ++i) {
251
0
    err->append((*i)->path());
252
0
    err->append(" -> ");
253
0
  }
254
0
  err->append((*start)->path());
255
256
0
  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
0
    err->append(" [-w phonycycle=err]");
260
0
  }
261
262
0
  return false;
263
0
}
264
265
bool DependencyScan::RecomputeOutputsDirty(Edge* edge, Node* most_recent_input,
266
0
                                           bool* outputs_dirty, string* err) {
267
0
  string command = edge->EvaluateCommand(/*incl_rsp_file=*/true);
268
0
  for (vector<Node*>::iterator o = edge->outputs_.begin();
269
0
       o != edge->outputs_.end(); ++o) {
270
0
    if (RecomputeOutputDirty(edge, most_recent_input, command, *o)) {
271
0
      *outputs_dirty = true;
272
0
      return true;
273
0
    }
274
0
  }
275
0
  return true;
276
0
}
277
278
bool DependencyScan::RecomputeOutputDirty(const Edge* edge,
279
                                          const Node* most_recent_input,
280
                                          const string& command,
281
0
                                          Node* output) {
282
0
  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
0
    if (edge->inputs_.empty() && !output->exists()) {
286
0
      EXPLAIN("output %s of phony edge with no inputs doesn't exist",
287
0
              output->path().c_str());
288
0
      return true;
289
0
    }
290
291
    // Update the mtime with the newest input. Dependents can thus call mtime()
292
    // on the fake node and get the latest mtime of the dependencies
293
0
    if (most_recent_input) {
294
0
      output->UpdatePhonyMtime(most_recent_input->mtime());
295
0
    }
296
297
    // Phony edges are clean, nothing to do
298
0
    return false;
299
0
  }
300
301
  // Dirty if we're missing the output.
302
0
  if (!output->exists()) {
303
0
    EXPLAIN("output %s doesn't exist", output->path().c_str());
304
0
    return true;
305
0
  }
306
307
0
  BuildLog::LogEntry* entry = 0;
308
309
  // If this is a restat rule, we may have cleaned the output in a
310
  // previous run and stored the command start time in the build log.
311
  // We don't want to consider a restat rule's outputs as dirty unless
312
  // an input changed since the last run, so we'll skip checking the
313
  // output file's actual mtime and simply check the recorded mtime from
314
  // the log against the most recent input's mtime (see below)
315
0
  bool used_restat = false;
316
0
  if (edge->GetBindingBool("restat") && build_log() &&
317
0
      (entry = build_log()->LookupByOutput(output->path()))) {
318
0
    used_restat = true;
319
0
  }
320
321
  // Dirty if the output is older than the input.
322
0
  if (!used_restat && most_recent_input && output->mtime() < most_recent_input->mtime()) {
323
0
    EXPLAIN("output %s older than most recent input %s "
324
0
            "(%" PRId64 " vs %" PRId64 ")",
325
0
            output->path().c_str(),
326
0
            most_recent_input->path().c_str(),
327
0
            output->mtime(), most_recent_input->mtime());
328
0
    return true;
329
0
  }
330
331
0
  if (build_log()) {
332
0
    bool generator = edge->GetBindingBool("generator");
333
0
    if (entry || (entry = build_log()->LookupByOutput(output->path()))) {
334
0
      if (!generator &&
335
0
          BuildLog::LogEntry::HashCommand(command) != entry->command_hash) {
336
        // May also be dirty due to the command changing since the last build.
337
        // But if this is a generator rule, the command changing does not make us
338
        // dirty.
339
0
        EXPLAIN("command line changed for %s", output->path().c_str());
340
0
        return true;
341
0
      }
342
0
      if (most_recent_input && entry->mtime < most_recent_input->mtime()) {
343
        // May also be dirty due to the mtime in the log being older than the
344
        // mtime of the most recent input.  This can occur even when the mtime
345
        // on disk is newer if a previous run wrote to the output file but
346
        // exited with an error or was interrupted. If this was a restat rule,
347
        // then we only check the recorded mtime against the most recent input
348
        // mtime and ignore the actual output's mtime above.
349
0
        EXPLAIN("recorded mtime of %s older than most recent input %s (%" PRId64 " vs %" PRId64 ")",
350
0
                output->path().c_str(), most_recent_input->path().c_str(),
351
0
                entry->mtime, most_recent_input->mtime());
352
0
        return true;
353
0
      }
354
0
    }
355
0
    if (!entry && !generator) {
356
0
      EXPLAIN("command line not found in log for %s", output->path().c_str());
357
0
      return true;
358
0
    }
359
0
  }
360
361
0
  return false;
362
0
}
363
364
0
bool DependencyScan::LoadDyndeps(Node* node, string* err) const {
365
0
  return dyndep_loader_.LoadDyndeps(node, err);
366
0
}
367
368
bool DependencyScan::LoadDyndeps(Node* node, DyndepFile* ddf,
369
0
                                 string* err) const {
370
0
  return dyndep_loader_.LoadDyndeps(node, ddf, err);
371
0
}
372
373
0
bool Edge::AllInputsReady() const {
374
0
  for (vector<Node*>::const_iterator i = inputs_.begin();
375
0
       i != inputs_.end(); ++i) {
376
0
    if ((*i)->in_edge() && !(*i)->in_edge()->outputs_ready())
377
0
      return false;
378
0
  }
379
0
  return true;
380
0
}
381
382
/// An Env for an Edge, providing $in and $out.
383
struct EdgeEnv : public Env {
384
  enum EscapeKind { kShellEscape, kDoNotEscape };
385
386
  EdgeEnv(const Edge* const edge, const EscapeKind escape)
387
85
      : edge_(edge), escape_in_out_(escape), recursive_(false) {}
388
  virtual string LookupVariable(const string& var);
389
390
  /// Given a span of Nodes, construct a list of paths suitable for a command
391
  /// line.
392
  std::string MakePathList(const Node* const* span, size_t size, char sep) const;
393
394
 private:
395
  std::vector<std::string> lookups_;
396
  const Edge* const edge_;
397
  EscapeKind escape_in_out_;
398
  bool recursive_;
399
};
400
401
256
string EdgeEnv::LookupVariable(const string& var) {
402
256
  if (var == "in" || var == "in_newline") {
403
105
    int explicit_deps_count = edge_->inputs_.size() - edge_->implicit_deps_ -
404
105
      edge_->order_only_deps_;
405
105
    return MakePathList(edge_->inputs_.data(), explicit_deps_count,
406
105
                        var == "in" ? ' ' : '\n');
407
151
  } else if (var == "out") {
408
0
    int explicit_outs_count = edge_->outputs_.size() - edge_->implicit_outs_;
409
0
    return MakePathList(&edge_->outputs_[0], explicit_outs_count, ' ');
410
0
  }
411
412
  // Technical note about the lookups_ vector.
413
  //
414
  // This is used to detect cycles during recursive variable expansion
415
  // which can be seen as a graph traversal problem. Consider the following
416
  // example:
417
  //
418
  //    rule something
419
  //      command = $foo $foo $var1
420
  //      var1 = $var2
421
  //      var2 = $var3
422
  //      var3 = $var1
423
  //      foo = FOO
424
  //
425
  // Each variable definition can be seen as a node in a graph that looks
426
  // like the following:
427
  //
428
  //   command --> foo
429
  //      |
430
  //      v
431
  //    var1 <-----.
432
  //      |        |
433
  //      v        |
434
  //    var2 ---> var3
435
  //
436
  // The lookups_ vector is used as a stack of visited nodes/variables
437
  // during recursive expansion. Entering a node adds an item to the
438
  // stack, leaving the node removes it.
439
  //
440
  // The recursive_ flag is used as a small performance optimization
441
  // to never record the starting node in the stack when beginning a new
442
  // expansion, since in most cases, expansions are not recursive
443
  // at all.
444
  //
445
151
  if (recursive_) {
446
66
    auto it = std::find(lookups_.begin(), lookups_.end(), var);
447
66
    if (it != lookups_.end()) {
448
0
      std::string cycle;
449
0
      for (; it != lookups_.end(); ++it)
450
0
        cycle.append(*it + " -> ");
451
0
      cycle.append(var);
452
0
      Fatal(("cycle in rule variables: " + cycle).c_str());
453
0
    }
454
66
  }
455
456
  // See notes on BindingEnv::LookupWithFallback.
457
151
  const EvalString* eval = edge_->rule_->GetBinding(var);
458
151
  bool record_varname = recursive_ && eval;
459
151
  if (record_varname)
460
0
    lookups_.push_back(var);
461
462
  // In practice, variables defined on rules never use another rule variable.
463
  // For performance, only start checking for cycles after the first lookup.
464
151
  recursive_ = true;
465
151
  std::string result = edge_->env_->LookupWithFallback(var, eval, this);
466
151
  if (record_varname)
467
0
    lookups_.pop_back();
468
151
  return result;
469
151
}
470
471
std::string EdgeEnv::MakePathList(const Node* const* const span,
472
105
                                  const size_t size, const char sep) const {
473
105
  string result;
474
3.66M
  for (const Node* const* i = span; i != span + size; ++i) {
475
3.66M
    if (!result.empty())
476
3.66M
      result.push_back(sep);
477
3.66M
    const string& path = (*i)->PathDecanonicalized();
478
3.66M
    if (escape_in_out_ == kShellEscape) {
479
#ifdef _WIN32
480
      GetWin32EscapedString(path, &result);
481
#else
482
0
      GetShellEscapedString(path, &result);
483
0
#endif
484
3.66M
    } else {
485
3.66M
      result.append(path);
486
3.66M
    }
487
3.66M
  }
488
105
  return result;
489
105
}
490
491
void Edge::CollectInputs(bool shell_escape,
492
0
                         std::vector<std::string>* out) const {
493
0
  for (std::vector<Node*>::const_iterator it = inputs_.begin();
494
0
       it != inputs_.end(); ++it) {
495
0
    std::string path = (*it)->PathDecanonicalized();
496
0
    if (shell_escape) {
497
0
      std::string unescaped;
498
0
      unescaped.swap(path);
499
#ifdef _WIN32
500
      GetWin32EscapedString(unescaped, &path);
501
#else
502
0
      GetShellEscapedString(unescaped, &path);
503
0
#endif
504
0
    }
505
0
#if __cplusplus >= 201103L
506
0
    out->push_back(std::move(path));
507
#else
508
    out->push_back(path);
509
#endif
510
0
  }
511
0
}
512
513
0
std::string Edge::EvaluateCommand(const bool incl_rsp_file) const {
514
0
  string command = GetBinding("command");
515
0
  if (incl_rsp_file) {
516
0
    string rspfile_content = GetBinding("rspfile_content");
517
0
    if (!rspfile_content.empty())
518
0
      command += ";rspfile=" + rspfile_content;
519
0
  }
520
0
  return command;
521
0
}
522
523
50
std::string Edge::GetBinding(const std::string& key) const {
524
50
  EdgeEnv env(this, EdgeEnv::kShellEscape);
525
50
  return env.LookupVariable(key);
526
50
}
527
528
0
bool Edge::GetBindingBool(const string& key) const {
529
0
  return !GetBinding(key).empty();
530
0
}
531
532
0
string Edge::GetUnescapedDepfile() const {
533
0
  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
534
0
  return env.LookupVariable("depfile");
535
0
}
536
537
35
string Edge::GetUnescapedDyndep() const {
538
35
  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
539
35
  return env.LookupVariable("dyndep");
540
35
}
541
542
0
std::string Edge::GetUnescapedRspfile() const {
543
0
  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
544
0
  return env.LookupVariable("rspfile");
545
0
}
546
547
0
void Edge::Dump(const char* prefix) const {
548
0
  printf("%s[ ", prefix);
549
0
  for (vector<Node*>::const_iterator i = inputs_.begin();
550
0
       i != inputs_.end() && *i != NULL; ++i) {
551
0
    printf("%s ", (*i)->path().c_str());
552
0
  }
553
0
  printf("--%s-> ", rule_->name().c_str());
554
0
  for (vector<Node*>::const_iterator i = outputs_.begin();
555
0
       i != outputs_.end() && *i != NULL; ++i) {
556
0
    printf("%s ", (*i)->path().c_str());
557
0
  }
558
0
  if (!validations_.empty()) {
559
0
    printf(" validations ");
560
0
    for (std::vector<Node*>::const_iterator i = validations_.begin();
561
0
         i != validations_.end() && *i != NULL; ++i) {
562
0
      printf("%s ", (*i)->path().c_str());
563
0
    }
564
0
  }
565
0
  if (pool_) {
566
0
    if (!pool_->name().empty()) {
567
0
      printf("(in pool '%s')", pool_->name().c_str());
568
0
    }
569
0
  } else {
570
0
    printf("(null pool?)");
571
0
  }
572
0
  printf("] 0x%p\n", this);
573
0
}
574
575
35
bool Edge::is_phony() const {
576
35
  return rule_ == &State::kPhonyRule;
577
35
}
578
579
0
bool Edge::use_console() const {
580
0
  return pool() == &State::kConsolePool;
581
0
}
582
583
35
bool Edge::maybe_phonycycle_diagnostic() const {
584
  // CMake 2.8.12.x and 3.0.x produced self-referencing phony rules
585
  // of the form "build a: phony ... a ...".   Restrict our
586
  // "phonycycle" diagnostic option to the form it used.
587
35
  return is_phony() && outputs_.size() == 1 && implicit_outs_ == 0 &&
588
35
      implicit_deps_ == 0;
589
35
}
590
591
// static
592
3.66M
string Node::PathDecanonicalized(const string& path, uint64_t slash_bits) {
593
3.66M
  string result = path;
594
#ifdef _WIN32
595
  uint64_t mask = 1;
596
  for (char* c = &result[0]; (c = strchr(c, '/')) != NULL;) {
597
    if (slash_bits & mask)
598
      *c = '\\';
599
    c++;
600
    mask <<= 1;
601
  }
602
#endif
603
3.66M
  return result;
604
3.66M
}
605
606
0
void Node::Dump(const char* prefix) const {
607
0
  printf("%s <%s 0x%p> mtime: %" PRId64 "%s, (:%s), ",
608
0
         prefix, path().c_str(), this,
609
0
         mtime(), exists() ? "" : " (:missing)",
610
0
         dirty() ? " dirty" : " clean");
611
0
  if (in_edge()) {
612
0
    in_edge()->Dump("in-edge: ");
613
0
  } else {
614
0
    printf("no in-edge\n");
615
0
  }
616
0
  printf(" out edges:\n");
617
0
  for (vector<Edge*>::const_iterator e = out_edges().begin();
618
0
       e != out_edges().end() && *e != NULL; ++e) {
619
0
    (*e)->Dump(" +- ");
620
0
  }
621
0
  if (!validation_out_edges().empty()) {
622
0
    printf(" validation out edges:\n");
623
0
    for (std::vector<Edge*>::const_iterator e = validation_out_edges().begin();
624
0
         e != validation_out_edges().end() && *e != NULL; ++e) {
625
0
      (*e)->Dump(" +- ");
626
0
    }
627
0
  }
628
0
}
629
630
0
bool ImplicitDepLoader::LoadDeps(Edge* edge, string* err) {
631
0
  string deps_type = edge->GetBinding("deps");
632
0
  if (!deps_type.empty())
633
0
    return LoadDepsFromLog(edge, err);
634
635
0
  string depfile = edge->GetUnescapedDepfile();
636
0
  if (!depfile.empty())
637
0
    return LoadDepFile(edge, depfile, err);
638
639
  // No deps to load.
640
0
  return true;
641
0
}
642
643
struct matches {
644
0
  explicit matches(std::vector<StringPiece>::iterator i) : i_(i) {}
645
646
0
  bool operator()(const Node* node) const {
647
0
    StringPiece opath = StringPiece(node->path());
648
0
    return *i_ == opath;
649
0
  }
650
651
  std::vector<StringPiece>::iterator i_;
652
};
653
654
bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path,
655
0
                                    string* err) {
656
0
  METRIC_RECORD("depfile load");
657
  // Read depfile content.  Treat a missing depfile as empty.
658
0
  string content;
659
0
  switch (disk_interface_->ReadFile(path, &content, err)) {
660
0
  case DiskInterface::Okay:
661
0
    break;
662
0
  case DiskInterface::NotFound:
663
0
    err->clear();
664
0
    break;
665
0
  case DiskInterface::OtherError:
666
0
    *err = "loading '" + path + "': " + *err;
667
0
    return false;
668
0
  }
669
  // On a missing depfile: return false and empty *err.
670
0
  if (content.empty()) {
671
0
    EXPLAIN("depfile '%s' is missing", path.c_str());
672
0
    return false;
673
0
  }
674
675
0
  DepfileParser depfile(depfile_parser_options_
676
0
                        ? *depfile_parser_options_
677
0
                        : DepfileParserOptions());
678
0
  string depfile_err;
679
0
  if (!depfile.Parse(&content, &depfile_err)) {
680
0
    *err = path + ": " + depfile_err;
681
0
    return false;
682
0
  }
683
684
0
  if (depfile.outs_.empty()) {
685
0
    *err = path + ": no outputs declared";
686
0
    return false;
687
0
  }
688
689
0
  uint64_t unused;
690
0
  std::vector<StringPiece>::iterator primary_out = depfile.outs_.begin();
691
0
  CanonicalizePath(const_cast<char*>(primary_out->str_), &primary_out->len_,
692
0
                   &unused);
693
694
  // Check that this depfile matches the edge's output, if not return false to
695
  // mark the edge as dirty.
696
0
  Node* first_output = edge->outputs_[0];
697
0
  StringPiece opath = StringPiece(first_output->path());
698
0
  if (opath != *primary_out) {
699
0
    EXPLAIN("expected depfile '%s' to mention '%s', got '%s'", path.c_str(),
700
0
            first_output->path().c_str(), primary_out->AsString().c_str());
701
0
    return false;
702
0
  }
703
704
  // Ensure that all mentioned outputs are outputs of the edge.
705
0
  for (std::vector<StringPiece>::iterator o = depfile.outs_.begin();
706
0
       o != depfile.outs_.end(); ++o) {
707
0
    matches m(o);
708
0
    if (std::find_if(edge->outputs_.begin(), edge->outputs_.end(), m) == edge->outputs_.end()) {
709
0
      *err = path + ": depfile mentions '" + o->AsString() + "' as an output, but no such output was declared";
710
0
      return false;
711
0
    }
712
0
  }
713
714
0
  return ProcessDepfileDeps(edge, &depfile.ins_, err);
715
0
}
716
717
bool ImplicitDepLoader::ProcessDepfileDeps(
718
0
    Edge* edge, std::vector<StringPiece>* depfile_ins, std::string* err) {
719
  // Preallocate space in edge->inputs_ to be filled in below.
720
0
  vector<Node*>::iterator implicit_dep =
721
0
      PreallocateSpace(edge, depfile_ins->size());
722
723
  // Add all its in-edges.
724
0
  for (std::vector<StringPiece>::iterator i = depfile_ins->begin();
725
0
       i != depfile_ins->end(); ++i, ++implicit_dep) {
726
0
    uint64_t slash_bits;
727
0
    CanonicalizePath(const_cast<char*>(i->str_), &i->len_, &slash_bits);
728
0
    Node* node = state_->GetNode(*i, slash_bits);
729
0
    *implicit_dep = node;
730
0
    node->AddOutEdge(edge);
731
0
    CreatePhonyInEdge(node);
732
0
  }
733
734
0
  return true;
735
0
}
736
737
0
bool ImplicitDepLoader::LoadDepsFromLog(Edge* edge, string* err) {
738
  // NOTE: deps are only supported for single-target edges.
739
0
  Node* output = edge->outputs_[0];
740
0
  DepsLog::Deps* deps = deps_log_ ? deps_log_->GetDeps(output) : NULL;
741
0
  if (!deps) {
742
0
    EXPLAIN("deps for '%s' are missing", output->path().c_str());
743
0
    return false;
744
0
  }
745
746
  // Deps are invalid if the output is newer than the deps.
747
0
  if (output->mtime() > deps->mtime) {
748
0
    EXPLAIN("stored deps info out of date for '%s' (%" PRId64 " vs %" PRId64 ")",
749
0
            output->path().c_str(), deps->mtime, output->mtime());
750
0
    return false;
751
0
  }
752
753
0
  vector<Node*>::iterator implicit_dep =
754
0
      PreallocateSpace(edge, deps->node_count);
755
0
  for (int i = 0; i < deps->node_count; ++i, ++implicit_dep) {
756
0
    Node* node = deps->nodes[i];
757
0
    *implicit_dep = node;
758
0
    node->AddOutEdge(edge);
759
0
    CreatePhonyInEdge(node);
760
0
  }
761
0
  return true;
762
0
}
763
764
vector<Node*>::iterator ImplicitDepLoader::PreallocateSpace(Edge* edge,
765
0
                                                            int count) {
766
0
  edge->inputs_.insert(edge->inputs_.end() - edge->order_only_deps_,
767
0
                       (size_t)count, 0);
768
0
  edge->implicit_deps_ += count;
769
0
  return edge->inputs_.end() - edge->order_only_deps_ - count;
770
0
}
771
772
0
void ImplicitDepLoader::CreatePhonyInEdge(Node* node) {
773
0
  if (node->in_edge())
774
0
    return;
775
776
0
  Edge* phony_edge = state_->AddEdge(&State::kPhonyRule);
777
0
  phony_edge->generated_by_dep_loader_ = true;
778
0
  node->set_in_edge(phony_edge);
779
0
  phony_edge->outputs_.push_back(node);
780
781
  // RecomputeDirty might not be called for phony_edge if a previous call
782
  // to RecomputeDirty had caused the file to be stat'ed.  Because previous
783
  // invocations of RecomputeDirty would have seen this node without an
784
  // input edge (and therefore ready), we have to set outputs_ready_ to true
785
  // to avoid a potential stuck build.  If we do call RecomputeDirty for
786
  // this node, it will simply set outputs_ready_ to the correct value.
787
0
  phony_edge->outputs_ready_ = true;
788
0
}