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