Ninja
build.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 "build.h"
16 
17 #include <assert.h>
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <functional>
22 
23 #if defined(__SVR4) && defined(__sun)
24 #include <sys/termios.h>
25 #endif
26 
27 #include "build_log.h"
28 #include "depfile_parser.h"
29 #include "deps_log.h"
30 #include "disk_interface.h"
31 #include "graph.h"
32 #include "msvc_helper.h"
33 #include "state.h"
34 #include "subprocess.h"
35 #include "util.h"
36 
37 namespace {
38 
39 /// A CommandRunner that doesn't actually run the commands.
40 struct DryRunCommandRunner : public CommandRunner {
41  virtual ~DryRunCommandRunner() {}
42 
43  // Overridden from CommandRunner:
44  virtual bool CanRunMore();
45  virtual bool StartCommand(Edge* edge);
46  virtual bool WaitForCommand(Result* result);
47 
48  private:
49  queue<Edge*> finished_;
50 };
51 
52 bool DryRunCommandRunner::CanRunMore() {
53  return true;
54 }
55 
56 bool DryRunCommandRunner::StartCommand(Edge* edge) {
57  finished_.push(edge);
58  return true;
59 }
60 
61 bool DryRunCommandRunner::WaitForCommand(Result* result) {
62  if (finished_.empty())
63  return false;
64 
65  result->status = ExitSuccess;
66  result->edge = finished_.front();
67  finished_.pop();
68  return true;
69 }
70 
71 } // namespace
72 
74  : config_(config),
75  start_time_millis_(GetTimeMillis()),
76  started_edges_(0), finished_edges_(0), total_edges_(0),
77  progress_status_format_(NULL),
78  overall_rate_(), current_rate_(config.parallelism) {
79 
80  // Don't do anything fancy in verbose mode.
83 
84  progress_status_format_ = getenv("NINJA_STATUS");
86  progress_status_format_ = "[%s/%t] ";
87 }
88 
90  total_edges_ = total;
91 }
92 
94  int start_time = (int)(GetTimeMillis() - start_time_millis_);
95  running_edges_.insert(make_pair(edge, start_time));
97 
98  PrintStatus(edge);
99 }
100 
102  bool success,
103  const string& output,
104  int* start_time,
105  int* end_time) {
106  int64_t now = GetTimeMillis();
107  ++finished_edges_;
108 
109  RunningEdgeMap::iterator i = running_edges_.find(edge);
110  *start_time = i->second;
111  *end_time = (int)(now - start_time_millis_);
112  running_edges_.erase(i);
113 
115  return;
116 
118  PrintStatus(edge);
119 
120  // Print the command that is spewing before printing its output.
121  if (!success)
122  printer_.PrintOnNewLine("FAILED: " + edge->EvaluateCommand() + "\n");
123 
124  if (!output.empty()) {
125  // ninja sets stdout and stderr of subprocesses to a pipe, to be able to
126  // check if the output is empty. Some compilers, e.g. clang, check
127  // isatty(stderr) to decide if they should print colored output.
128  // To make it possible to use colored output with ninja, subprocesses should
129  // be run with a flag that forces them to always print color escape codes.
130  // To make sure these escape codes don't show up in a file if ninja's output
131  // is piped to a file, ninja strips ansi escape codes again if it's not
132  // writing to a |smart_terminal_|.
133  // (Launching subprocesses in pseudo ttys doesn't work because there are
134  // only a few hundred available on some systems, and ninja can launch
135  // thousands of parallel compile commands.)
136  // TODO: There should be a flag to disable escape code stripping.
137  string final_output;
139  final_output = StripAnsiEscapeCodes(output);
140  else
141  final_output = output;
142  printer_.PrintOnNewLine(final_output);
143  }
144 }
145 
148 }
149 
151  const char* progress_status_format) const {
152  string out;
153  char buf[32];
154  int percent;
155  for (const char* s = progress_status_format; *s != '\0'; ++s) {
156  if (*s == '%') {
157  ++s;
158  switch (*s) {
159  case '%':
160  out.push_back('%');
161  break;
162 
163  // Started edges.
164  case 's':
165  snprintf(buf, sizeof(buf), "%d", started_edges_);
166  out += buf;
167  break;
168 
169  // Total edges.
170  case 't':
171  snprintf(buf, sizeof(buf), "%d", total_edges_);
172  out += buf;
173  break;
174 
175  // Running edges.
176  case 'r':
177  snprintf(buf, sizeof(buf), "%d", started_edges_ - finished_edges_);
178  out += buf;
179  break;
180 
181  // Unstarted edges.
182  case 'u':
183  snprintf(buf, sizeof(buf), "%d", total_edges_ - started_edges_);
184  out += buf;
185  break;
186 
187  // Finished edges.
188  case 'f':
189  snprintf(buf, sizeof(buf), "%d", finished_edges_);
190  out += buf;
191  break;
192 
193  // Overall finished edges per second.
194  case 'o':
196  snprinfRate(overall_rate_.rate(), buf, "%.1f");
197  out += buf;
198  break;
199 
200  // Current rate, average over the last '-j' jobs.
201  case 'c':
203  snprinfRate(current_rate_.rate(), buf, "%.1f");
204  out += buf;
205  break;
206 
207  // Percentage
208  case 'p':
209  percent = (100 * started_edges_) / total_edges_;
210  snprintf(buf, sizeof(buf), "%3i%%", percent);
211  out += buf;
212  break;
213 
214  case 'e': {
215  double elapsed = overall_rate_.Elapsed();
216  snprintf(buf, sizeof(buf), "%.3f", elapsed);
217  out += buf;
218  break;
219  }
220 
221  default:
222  Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s);
223  return "";
224  }
225  } else {
226  out.push_back(*s);
227  }
228  }
229 
230  return out;
231 }
232 
235  return;
236 
237  bool force_full_command = config_.verbosity == BuildConfig::VERBOSE;
238 
239  string to_print = edge->GetBinding("description");
240  if (to_print.empty() || force_full_command)
241  to_print = edge->GetBinding("command");
242 
243  if (finished_edges_ == 0) {
246  }
247  to_print = FormatProgressStatus(progress_status_format_) + to_print;
248 
249  printer_.Print(to_print,
250  force_full_command ? LinePrinter::FULL : LinePrinter::ELIDE);
251 }
252 
253 Plan::Plan() : command_edges_(0), wanted_edges_(0) {}
254 
255 bool Plan::AddTarget(Node* node, string* err) {
256  vector<Node*> stack;
257  return AddSubTarget(node, &stack, err);
258 }
259 
260 bool Plan::AddSubTarget(Node* node, vector<Node*>* stack, string* err) {
261  Edge* edge = node->in_edge();
262  if (!edge) { // Leaf node.
263  if (node->dirty()) {
264  string referenced;
265  if (!stack->empty())
266  referenced = ", needed by '" + stack->back()->path() + "',";
267  *err = "'" + node->path() + "'" + referenced + " missing "
268  "and no known rule to make it";
269  }
270  return false;
271  }
272 
273  if (CheckDependencyCycle(node, stack, err))
274  return false;
275 
276  if (edge->outputs_ready())
277  return false; // Don't need to do anything.
278 
279  // If an entry in want_ does not already exist for edge, create an entry which
280  // maps to false, indicating that we do not want to build this entry itself.
281  pair<map<Edge*, bool>::iterator, bool> want_ins =
282  want_.insert(make_pair(edge, false));
283  bool& want = want_ins.first->second;
284 
285  // If we do need to build edge and we haven't already marked it as wanted,
286  // mark it now.
287  if (node->dirty() && !want) {
288  want = true;
289  ++wanted_edges_;
290  if (edge->AllInputsReady())
291  ScheduleWork(edge);
292  if (!edge->is_phony())
293  ++command_edges_;
294  }
295 
296  if (!want_ins.second)
297  return true; // We've already processed the inputs.
298 
299  stack->push_back(node);
300  for (vector<Node*>::iterator i = edge->inputs_.begin();
301  i != edge->inputs_.end(); ++i) {
302  if (!AddSubTarget(*i, stack, err) && !err->empty())
303  return false;
304  }
305  assert(stack->back() == node);
306  stack->pop_back();
307 
308  return true;
309 }
310 
311 bool Plan::CheckDependencyCycle(Node* node, vector<Node*>* stack, string* err) {
312  vector<Node*>::reverse_iterator ri =
313  find(stack->rbegin(), stack->rend(), node);
314  if (ri == stack->rend())
315  return false;
316 
317  // Add this node onto the stack to make it clearer where the loop
318  // is.
319  stack->push_back(node);
320 
321  vector<Node*>::iterator start = find(stack->begin(), stack->end(), node);
322  *err = "dependency cycle: ";
323  for (vector<Node*>::iterator i = start; i != stack->end(); ++i) {
324  if (i != start)
325  err->append(" -> ");
326  err->append((*i)->path());
327  }
328  return true;
329 }
330 
332  if (ready_.empty())
333  return NULL;
334  set<Edge*>::iterator i = ready_.begin();
335  Edge* edge = *i;
336  ready_.erase(i);
337  return edge;
338 }
339 
341  Pool* pool = edge->pool();
342  if (pool->ShouldDelayEdge()) {
343  // The graph is not completely clean. Some Nodes have duplicate Out edges.
344  // We need to explicitly ignore these here, otherwise their work will get
345  // scheduled twice (see https://github.com/martine/ninja/pull/519)
346  if (ready_.count(edge)) {
347  return;
348  }
349  pool->DelayEdge(edge);
350  pool->RetrieveReadyEdges(&ready_);
351  } else {
352  pool->EdgeScheduled(*edge);
353  ready_.insert(edge);
354  }
355 }
356 
358  edge->pool()->EdgeFinished(*edge);
359  edge->pool()->RetrieveReadyEdges(&ready_);
360 }
361 
363  map<Edge*, bool>::iterator i = want_.find(edge);
364  assert(i != want_.end());
365  if (i->second)
366  --wanted_edges_;
367  want_.erase(i);
368  edge->outputs_ready_ = true;
369 
370  // See if this job frees up any delayed jobs
371  ResumeDelayedJobs(edge);
372 
373  // Check off any nodes we were waiting for with this edge.
374  for (vector<Node*>::iterator i = edge->outputs_.begin();
375  i != edge->outputs_.end(); ++i) {
376  NodeFinished(*i);
377  }
378 }
379 
381  // See if we we want any edges from this node.
382  for (vector<Edge*>::const_iterator i = node->out_edges().begin();
383  i != node->out_edges().end(); ++i) {
384  map<Edge*, bool>::iterator want_i = want_.find(*i);
385  if (want_i == want_.end())
386  continue;
387 
388  // See if the edge is now ready.
389  if ((*i)->AllInputsReady()) {
390  if (want_i->second) {
391  ScheduleWork(*i);
392  } else {
393  // We do not need to build this edge, but we might need to build one of
394  // its dependents.
395  EdgeFinished(*i);
396  }
397  }
398  }
399 }
400 
401 void Plan::CleanNode(DependencyScan* scan, Node* node) {
402  node->set_dirty(false);
403 
404  for (vector<Edge*>::const_iterator ei = node->out_edges().begin();
405  ei != node->out_edges().end(); ++ei) {
406  // Don't process edges that we don't actually want.
407  map<Edge*, bool>::iterator want_i = want_.find(*ei);
408  if (want_i == want_.end() || !want_i->second)
409  continue;
410 
411  // If all non-order-only inputs for this edge are now clean,
412  // we might have changed the dirty state of the outputs.
413  vector<Node*>::iterator
414  begin = (*ei)->inputs_.begin(),
415  end = (*ei)->inputs_.end() - (*ei)->order_only_deps_;
416  if (find_if(begin, end, mem_fun(&Node::dirty)) == end) {
417  // Recompute most_recent_input and command.
418  Node* most_recent_input = NULL;
419  for (vector<Node*>::iterator ni = begin; ni != end; ++ni) {
420  if (!most_recent_input || (*ni)->mtime() > most_recent_input->mtime())
421  most_recent_input = *ni;
422  }
423  string command = (*ei)->EvaluateCommand(true);
424 
425  // Now, recompute the dirty state of each output.
426  bool all_outputs_clean = true;
427  for (vector<Node*>::iterator ni = (*ei)->outputs_.begin();
428  ni != (*ei)->outputs_.end(); ++ni) {
429  if (!(*ni)->dirty())
430  continue;
431 
432  if (scan->RecomputeOutputDirty(*ei, most_recent_input, 0,
433  command, *ni)) {
434  (*ni)->MarkDirty();
435  all_outputs_clean = false;
436  } else {
437  CleanNode(scan, *ni);
438  }
439  }
440 
441  // If we cleaned all outputs, mark the node as not wanted.
442  if (all_outputs_clean) {
443  want_i->second = false;
444  --wanted_edges_;
445  if (!(*ei)->is_phony())
446  --command_edges_;
447  }
448  }
449  }
450 }
451 
452 void Plan::Dump() {
453  printf("pending: %d\n", (int)want_.size());
454  for (map<Edge*, bool>::iterator i = want_.begin(); i != want_.end(); ++i) {
455  if (i->second)
456  printf("want ");
457  i->first->Dump();
458  }
459  printf("ready: %d\n", (int)ready_.size());
460 }
461 
463  explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
464  virtual ~RealCommandRunner() {}
465  virtual bool CanRunMore();
466  virtual bool StartCommand(Edge* edge);
467  virtual bool WaitForCommand(Result* result);
468  virtual vector<Edge*> GetActiveEdges();
469  virtual void Abort();
470 
473  map<Subprocess*, Edge*> subproc_to_edge_;
474 };
475 
477  vector<Edge*> edges;
478  for (map<Subprocess*, Edge*>::iterator i = subproc_to_edge_.begin();
479  i != subproc_to_edge_.end(); ++i)
480  edges.push_back(i->second);
481  return edges;
482 }
483 
485  subprocs_.Clear();
486 }
487 
489  return ((int)subprocs_.running_.size()) < config_.parallelism
490  && ((subprocs_.running_.empty() || config_.max_load_average <= 0.0f)
492 }
493 
495  string command = edge->EvaluateCommand();
496  Subprocess* subproc = subprocs_.Add(command);
497  if (!subproc)
498  return false;
499  subproc_to_edge_.insert(make_pair(subproc, edge));
500 
501  return true;
502 }
503 
505  Subprocess* subproc;
506  while ((subproc = subprocs_.NextFinished()) == NULL) {
507  bool interrupted = subprocs_.DoWork();
508  if (interrupted)
509  return false;
510  }
511 
512  result->status = subproc->Finish();
513  result->output = subproc->GetOutput();
514 
515  map<Subprocess*, Edge*>::iterator i = subproc_to_edge_.find(subproc);
516  result->edge = i->second;
517  subproc_to_edge_.erase(i);
518 
519  delete subproc;
520  return true;
521 }
522 
523 Builder::Builder(State* state, const BuildConfig& config,
524  BuildLog* build_log, DepsLog* deps_log,
525  DiskInterface* disk_interface)
526  : state_(state), config_(config), disk_interface_(disk_interface),
527  scan_(state, build_log, deps_log, disk_interface) {
528  status_ = new BuildStatus(config);
529 }
530 
532  Cleanup();
533 }
534 
536  if (command_runner_.get()) {
537  vector<Edge*> active_edges = command_runner_->GetActiveEdges();
538  command_runner_->Abort();
539 
540  for (vector<Edge*>::iterator i = active_edges.begin();
541  i != active_edges.end(); ++i) {
542  string depfile = (*i)->GetBinding("depfile");
543  for (vector<Node*>::iterator ni = (*i)->outputs_.begin();
544  ni != (*i)->outputs_.end(); ++ni) {
545  // Only delete this output if it was actually modified. This is
546  // important for things like the generator where we don't want to
547  // delete the manifest file if we can avoid it. But if the rule
548  // uses a depfile, always delete. (Consider the case where we
549  // need to rebuild an output because of a modified header file
550  // mentioned in a depfile, and the command touches its depfile
551  // but is interrupted before it touches its output file.)
552  if (!depfile.empty() ||
553  (*ni)->mtime() != disk_interface_->Stat((*ni)->path())) {
554  disk_interface_->RemoveFile((*ni)->path());
555  }
556  }
557  if (!depfile.empty())
558  disk_interface_->RemoveFile(depfile);
559  }
560  }
561 }
562 
563 Node* Builder::AddTarget(const string& name, string* err) {
564  Node* node = state_->LookupNode(name);
565  if (!node) {
566  *err = "unknown target: '" + name + "'";
567  return NULL;
568  }
569  if (!AddTarget(node, err))
570  return NULL;
571  return node;
572 }
573 
574 bool Builder::AddTarget(Node* node, string* err) {
576  if (Edge* in_edge = node->in_edge()) {
577  if (!scan_.RecomputeDirty(in_edge, err))
578  return false;
579  if (in_edge->outputs_ready())
580  return true; // Nothing to do.
581  }
582 
583  if (!plan_.AddTarget(node, err))
584  return false;
585 
586  return true;
587 }
588 
590  return !plan_.more_to_do();
591 }
592 
593 bool Builder::Build(string* err) {
594  assert(!AlreadyUpToDate());
595 
597  int pending_commands = 0;
598  int failures_allowed = config_.failures_allowed;
599 
600  // Set up the command runner if we haven't done so already.
601  if (!command_runner_.get()) {
602  if (config_.dry_run)
603  command_runner_.reset(new DryRunCommandRunner);
604  else
606  }
607 
608  // This main loop runs the entire build process.
609  // It is structured like this:
610  // First, we attempt to start as many commands as allowed by the
611  // command runner.
612  // Second, we attempt to wait for / reap the next finished command.
613  while (plan_.more_to_do()) {
614  // See if we can start any more commands.
615  if (failures_allowed && command_runner_->CanRunMore()) {
616  if (Edge* edge = plan_.FindWork()) {
617  if (!StartEdge(edge, err)) {
619  return false;
620  }
621 
622  if (edge->is_phony()) {
623  plan_.EdgeFinished(edge);
624  } else {
625  ++pending_commands;
626  }
627 
628  // We made some progress; go back to the main loop.
629  continue;
630  }
631  }
632 
633  // See if we can reap any finished commands.
634  if (pending_commands) {
635  CommandRunner::Result result;
636  if (!command_runner_->WaitForCommand(&result) ||
637  result.status == ExitInterrupted) {
639  *err = "interrupted by user";
640  return false;
641  }
642 
643  --pending_commands;
644  FinishCommand(&result);
645 
646  if (!result.success()) {
647  if (failures_allowed)
648  failures_allowed--;
649  }
650 
651  // We made some progress; start the main loop over.
652  continue;
653  }
654 
655  // If we get here, we cannot make any more progress.
657  if (failures_allowed == 0) {
658  if (config_.failures_allowed > 1)
659  *err = "subcommands failed";
660  else
661  *err = "subcommand failed";
662  } else if (failures_allowed < config_.failures_allowed)
663  *err = "cannot make progress due to previous errors";
664  else
665  *err = "stuck [this is a bug]";
666 
667  return false;
668  }
669 
671  return true;
672 }
673 
674 bool Builder::StartEdge(Edge* edge, string* err) {
675  METRIC_RECORD("StartEdge");
676  if (edge->is_phony())
677  return true;
678 
679  status_->BuildEdgeStarted(edge);
680 
681  // Create directories necessary for outputs.
682  // XXX: this will block; do we care?
683  for (vector<Node*>::iterator i = edge->outputs_.begin();
684  i != edge->outputs_.end(); ++i) {
685  if (!disk_interface_->MakeDirs((*i)->path()))
686  return false;
687  }
688 
689  // Create response file, if needed
690  // XXX: this may also block; do we care?
691  string rspfile = edge->GetBinding("rspfile");
692  if (!rspfile.empty()) {
693  string content = edge->GetBinding("rspfile_content");
694  if (!disk_interface_->WriteFile(rspfile, content))
695  return false;
696  }
697 
698  // start command computing and run it
699  if (!command_runner_->StartCommand(edge)) {
700  err->assign("command '" + edge->EvaluateCommand() + "' failed.");
701  return false;
702  }
703 
704  return true;
705 }
706 
708  METRIC_RECORD("FinishCommand");
709 
710  Edge* edge = result->edge;
711 
712  // First try to extract dependencies from the result, if any.
713  // This must happen first as it filters the command output (we want
714  // to filter /showIncludes output, even on compile failure) and
715  // extraction itself can fail, which makes the command fail from a
716  // build perspective.
717  vector<Node*> deps_nodes;
718  string deps_type = edge->GetBinding("deps");
719  if (!deps_type.empty()) {
720  string extract_err;
721  if (!ExtractDeps(result, deps_type, &deps_nodes, &extract_err) &&
722  result->success()) {
723  if (!result->output.empty())
724  result->output.append("\n");
725  result->output.append(extract_err);
726  result->status = ExitFailure;
727  }
728  }
729 
730  int start_time, end_time;
731  status_->BuildEdgeFinished(edge, result->success(), result->output,
732  &start_time, &end_time);
733 
734  // The rest of this function only applies to successful commands.
735  if (!result->success())
736  return;
737 
738  // Restat the edge outputs, if necessary.
739  TimeStamp restat_mtime = 0;
740  if (edge->GetBindingBool("restat") && !config_.dry_run) {
741  bool node_cleaned = false;
742 
743  for (vector<Node*>::iterator i = edge->outputs_.begin();
744  i != edge->outputs_.end(); ++i) {
745  TimeStamp new_mtime = disk_interface_->Stat((*i)->path());
746  if ((*i)->mtime() == new_mtime) {
747  // The rule command did not change the output. Propagate the clean
748  // state through the build graph.
749  // Note that this also applies to nonexistent outputs (mtime == 0).
750  plan_.CleanNode(&scan_, *i);
751  node_cleaned = true;
752  }
753  }
754 
755  if (node_cleaned) {
756  // If any output was cleaned, find the most recent mtime of any
757  // (existing) non-order-only input or the depfile.
758  for (vector<Node*>::iterator i = edge->inputs_.begin();
759  i != edge->inputs_.end() - edge->order_only_deps_; ++i) {
760  TimeStamp input_mtime = disk_interface_->Stat((*i)->path());
761  if (input_mtime > restat_mtime)
762  restat_mtime = input_mtime;
763  }
764 
765  string depfile = edge->GetBinding("depfile");
766  if (restat_mtime != 0 && !depfile.empty()) {
767  TimeStamp depfile_mtime = disk_interface_->Stat(depfile);
768  if (depfile_mtime > restat_mtime)
769  restat_mtime = depfile_mtime;
770  }
771 
772  // The total number of edges in the plan may have changed as a result
773  // of a restat.
775  }
776  }
777 
778  plan_.EdgeFinished(edge);
779 
780  // Delete any left over response file.
781  string rspfile = edge->GetBinding("rspfile");
782  if (!rspfile.empty())
783  disk_interface_->RemoveFile(rspfile);
784 
785  if (scan_.build_log()) {
786  scan_.build_log()->RecordCommand(edge, start_time, end_time,
787  restat_mtime);
788  }
789 
790  if (!deps_type.empty() && !config_.dry_run) {
791  assert(edge->outputs_.size() == 1 && "should have been rejected by parser");
792  Node* out = edge->outputs_[0];
793  TimeStamp deps_mtime = disk_interface_->Stat(out->path());
794  scan_.deps_log()->RecordDeps(out, deps_mtime, deps_nodes);
795  }
796 
797 }
798 
800  const string& deps_type,
801  vector<Node*>* deps_nodes,
802  string* err) {
803 #ifdef _WIN32
804  if (deps_type == "msvc") {
805  CLParser parser;
806  result->output = parser.Parse(result->output);
807  for (set<string>::iterator i = parser.includes_.begin();
808  i != parser.includes_.end(); ++i) {
809  deps_nodes->push_back(state_->GetNode(*i));
810  }
811  } else
812 #endif
813  if (deps_type == "gcc") {
814  string depfile = result->edge->GetBinding("depfile");
815  if (depfile.empty()) {
816  *err = string("edge with deps=gcc but no depfile makes no sense");
817  return false;
818  }
819 
820  string content = disk_interface_->ReadFile(depfile, err);
821  if (!err->empty())
822  return false;
823  if (content.empty())
824  return true;
825 
826  DepfileParser deps;
827  if (!deps.Parse(&content, err))
828  return false;
829 
830  // XXX check depfile matches expected output.
831  deps_nodes->reserve(deps.ins_.size());
832  for (vector<StringPiece>::iterator i = deps.ins_.begin();
833  i != deps.ins_.end(); ++i) {
834  if (!CanonicalizePath(const_cast<char*>(i->str_), &i->len_, err))
835  return false;
836  deps_nodes->push_back(state_->GetNode(*i));
837  }
838 
839  if (disk_interface_->RemoveFile(depfile) < 0) {
840  *err = string("deleting depfile: ") + strerror(errno) + string("\n");
841  return false;
842  }
843  } else {
844  Fatal("unknown deps type '%s'", deps_type.c_str());
845  }
846 
847  return true;
848 }
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Definition: subprocess.h:74
bool is_phony() const
Definition: graph.cc:314
virtual string ReadFile(const string &path, string *err)=0
Read a file to a string. Fill in |err| on error.
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:103
Verbosity verbosity
Definition: build.h:133
SubprocessSet subprocs_
Definition: build.cc:472
map< Subprocess *, Edge * > subproc_to_edge_
Definition: build.cc:473
int order_only_deps_
Definition: graph.h:175
void BuildEdgeFinished(Edge *edge, bool success, const string &output, int *start_time, int *end_time)
Definition: build.cc:101
BuildStatus(const BuildConfig &config)
Definition: build.cc:73
TimeStamp mtime() const
Definition: graph.h:74
virtual ~RealCommandRunner()
Definition: build.cc:464
double Elapsed() const
Definition: build.h:236
RateInfo overall_rate_
Definition: build.h:275
Subprocess * NextFinished()
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:139
bool more_to_do() const
Returns true if there's more work to be done.
Definition: build.h:54
Parser for the dependency information emitted by gcc's -M flags.
SlidingRateInfo current_rate_
Definition: build.h:276
void EdgeScheduled(const Edge &edge)
informs this Pool that the given edge is committed to be run.
Definition: state.cc:26
Node * GetNode(StringPiece path)
Definition: state.cc:112
Plan()
Definition: build.cc:253
void UpdateRate(int edges)
Definition: build.h:239
bool RecomputeOutputDirty(Edge *edge, Node *most_recent_input, TimeStamp deps_mtime, const string &command, Node *output)
Recompute whether a given single output should be marked dirty.
Definition: graph.cc:144
bool RecomputeDirty(Edge *edge, string *err)
Examine inputs, outputs, and command lines to judge whether an edge needs to be re-run, and update outputs_ready_ and each outputs' |dirty_| state accordingly.
Definition: graph.cc:60
set< Edge * > ready_
Definition: build.h:91
bool AddSubTarget(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:260
The result of waiting for a command.
Definition: build.h:109
void set_dirty(bool dirty)
Definition: graph.h:77
bool AddTarget(Node *node, string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:255
bool MakeDirs(const string &path)
Create all the parent directories for path; like mkdir -p basename path.
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
Definition: graph.h:35
bool success() const
Definition: build.h:114
Edge * FindWork()
Definition: build.cc:331
virtual bool StartCommand(Edge *edge)
Definition: build.cc:494
void ResumeDelayedJobs(Edge *edge)
Allows jobs blocking on |edge| to potentially resume.
Definition: build.cc:357
void ScheduleWork(Edge *edge)
Submits a ready edge as a candidate for execution.
Definition: build.cc:340
bool Parse(string *content, string *err)
Parse an input file.
bool ShouldDelayEdge() const
true if the Pool might delay this edge
Definition: state.h:49
bool StatIfNecessary(DiskInterface *disk_interface)
Return true if we needed to stat.
Definition: graph.h:47
State * state_
Definition: build.h:173
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:174
Edge * in_edge() const
Definition: graph.h:80
bool is_smart_terminal() const
Definition: line_printer.h:26
int64_t GetTimeMillis()
Get the current time as relative to some epoch.
Definition: metrics.cc:122
int finished_edges_
Definition: build.h:214
bool GetBindingBool(const string &key)
Definition: graph.cc:289
void PrintOnNewLine(const string &to_print)
Prints a string on a new line, not overprinting previous output.
const BuildConfig & config_
Definition: build.h:209
int TimeStamp
Definition: timestamp.h:22
void CleanNode(DependencyScan *scan, Node *node)
Clean the given node during the build.
Definition: build.cc:401
bool outputs_ready() const
Definition: graph.h:164
Pool * pool() const
Definition: graph.h:162
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:137
void UpdateRate(int update_hint)
Definition: build.h:255
Store a log of every command ran for every build.
Definition: build_log.h:35
int started_edges_
Definition: build.h:214
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
Definition: build.cc:504
string EvaluateCommand(bool incl_rsp_file=false)
Expand all variables in a command and return it as a string.
Definition: graph.cc:274
Subprocess * Add(const string &command)
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:589
vector< Subprocess * > running_
Definition: subprocess.h:83
const BuildConfig & config_
Definition: build.cc:471
void BuildEdgeStarted(Edge *edge)
Definition: build.cc:93
DiskInterface * disk_interface_
Definition: build.h:183
bool CanonicalizePath(string *path, string *err)
Canonicalize a path like "foo/../bar.h" into just "bar.h".
Definition: util.cc:87
void MarkDirty()
Definition: graph.h:78
ExitStatus Finish()
Returns ExitSuccess on successful process exit, ExitInterrupted if the process was interrupted...
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:67
string Parse(const string &output)
Parse the full output of cl, returning the output (if any) that should printed.
void RecordCommand(Edge *edge, int start_time, int end_time, TimeStamp restat_mtime=0)
Definition: build_log.cc:139
void EdgeFinished(Edge *edge)
Mark an edge as done building.
Definition: build.cc:362
virtual bool WriteFile(const string &path, const string &contents)=0
Create a file, with the specified name and contents Returns true on success, false on failure...
vector< Node * > inputs_
Definition: graph.h:156
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:63
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:21
const string & GetOutput() const
double GetLoadAverage()
Definition: util.cc:340
bool outputs_ready_
Definition: graph.h:159
int parallelism
Definition: build.h:135
int failures_allowed
Definition: build.h:136
Builder(State *state, const BuildConfig &config, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface)
Definition: build.cc:523
BuildLog * build_log() const
Definition: graph.h:249
Subprocess wraps a single async subprocess.
Definition: subprocess.h:35
~Builder()
Definition: build.cc:531
map< Edge *, bool > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:89
bool dirty() const
Definition: graph.h:76
virtual vector< Edge * > GetActiveEdges()
Definition: build.cc:476
int64_t start_time_millis_
Time the build started.
Definition: build.h:212
virtual void Abort()
Definition: build.cc:484
int total_edges_
Definition: build.h:214
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:97
void set_smart_terminal(bool smart)
Definition: line_printer.h:27
void FinishCommand(CommandRunner::Result *result)
Definition: build.cc:707
ExitStatus status
Definition: build.h:112
void DelayEdge(Edge *edge)
adds the given edge to this Pool to be delayed.
Definition: state.cc:36
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:535
Node * LookupNode(StringPiece path)
Definition: state.cc:121
vector< StringPiece > ins_
A pool for delayed edges.
Definition: state.h:39
#define METRIC_RECORD(name)
The primary interface to metrics.
Definition: metrics.h:85
auto_ptr< CommandRunner > command_runner_
Definition: build.h:176
const string & path() const
Definition: graph.h:73
void RetrieveReadyEdges(set< Edge * > *ready_queue)
Pool will add zero or more edges to the ready_queue.
Definition: state.cc:41
void PlanHasTotalEdges(int total)
Definition: build.cc:89
void NodeFinished(Node *node)
Definition: build.cc:380
bool CheckDependencyCycle(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:311
string StripAnsiEscapeCodes(const string &in)
Removes all Ansi escape codes (http://www.termsys.demon.co.uk/vtansi.htm).
Definition: util.cc:280
void Fatal(const char *msg,...)
Log a fatal message and exit.
Definition: util.cc:51
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:192
bool ExtractDeps(CommandRunner::Result *result, const string &deps_type, vector< Node * > *deps_nodes, string *err)
Definition: build.cc:799
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:224
Plan plan_
Definition: build.h:175
string GetBinding(const string &key)
Definition: graph.cc:284
Visual Studio's cl.exe requires some massaging to work with Ninja; for example, it emits include info...
Definition: msvc_helper.h:26
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:230
void PrintStatus(Edge *edge)
Definition: build.cc:233
set< string > includes_
Definition: msvc_helper.h:46
void BuildFinished()
Definition: build.cc:146
void EdgeFinished(const Edge &edge)
informs this Pool that the given edge is no longer runnable, and should relinquish its resources back...
Definition: state.cc:31
virtual int RemoveFile(const string &path)=0
Remove the file named path.
virtual bool CanRunMore()
Definition: build.cc:488
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:124
Global state (file status, loaded rules) for a single run.
Definition: state.h:83
bool StartEdge(Edge *edge, string *err)
Definition: build.cc:674
bool AllInputsReady() const
Return true if all inputs' in-edges are ready.
Definition: graph.cc:214
void Dump()
Dumps the current state of the plan.
Definition: build.cc:452
void Print(string to_print, LineType type)
Overprints the current line.
Definition: line_printer.cc:45
bool RecordDeps(Node *node, TimeStamp mtime, const vector< Node * > &nodes)
Definition: deps_log.cc:71
RunningEdgeMap running_edges_
Definition: build.h:218
bool Build(string *err)
Run the build.
Definition: build.cc:593
BuildStatus * status_
Definition: build.h:177
string FormatProgressStatus(const char *progress_status_format) const
Format the progress status string by replacing the placeholders.
Definition: build.cc:150
LinePrinter printer_
Prints progress output.
Definition: build.h:221
Node * AddTarget(const string &name, string *err)
Definition: build.cc:563
bool dry_run
Definition: build.h:134
DependencyScan scan_
Definition: build.h:184
const vector< Edge * > & out_edges() const
Definition: graph.h:86
virtual TimeStamp Stat(const string &path)=0
stat() a file, returning the mtime, or 0 if missing and -1 on other errors.
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:94
void snprinfRate(double rate, char(&buf)[S], const char *format) const
Definition: build.h:227
DepsLog * deps_log() const
Definition: graph.h:256
RealCommandRunner(const BuildConfig &config)
Definition: build.cc:463
vector< Node * > outputs_
Definition: graph.h:157