• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <climits>
22 #include <stdint.h>
23 #include <functional>
24 #include <iostream>
25 
26 #if defined(__SVR4) && defined(__sun)
27 #include <sys/termios.h>
28 #endif
29 
30 #include "build_log.h"
31 #include "clparser.h"
32 #include "debug_flags.h"
33 #include "depfile_parser.h"
34 #include "deps_log.h"
35 #include "disk_interface.h"
36 #include "graph.h"
37 #include "metrics.h"
38 #include "state.h"
39 #include "status.h"
40 #include "subprocess.h"
41 #include "util.h"
42 
43 using namespace std;
44 
45 namespace {
46 
47 /// A CommandRunner that doesn't actually run the commands.
48 struct DryRunCommandRunner : public CommandRunner {
~DryRunCommandRunner__anon5de130dc0111::DryRunCommandRunner49     virtual ~DryRunCommandRunner() {}
50 
51     // Overridden from CommandRunner:
52     virtual size_t CanRunMore() const;
53     virtual bool StartCommand(Edge* edge);
54     virtual bool WaitForCommand(Result* result);
55 
56     private:
57         queue<Edge*> finished_;
58 };
59 
CanRunMore() const60 size_t DryRunCommandRunner::CanRunMore() const {
61     return SIZE_MAX;
62 }
63 
StartCommand(Edge * edge)64 bool DryRunCommandRunner::StartCommand(Edge* edge) {
65     finished_.push(edge);
66     return true;
67 }
68 
WaitForCommand(Result * result)69 bool DryRunCommandRunner::WaitForCommand(Result* result) {
70     if (finished_.empty())
71         return false;
72 
73     result->status = ExitSuccess;
74     result->edge = finished_.front();
75     finished_.pop();
76     return true;
77 }
78 
79 }  // namespace
80 
Plan(Builder * builder)81 Plan::Plan(Builder* builder)
82     : builder_(builder)
83     , command_edges_(0)
84     , wanted_edges_(0)
85 {}
86 
Reset()87 void Plan::Reset() {
88     command_edges_ = 0;
89     wanted_edges_ = 0;
90     ready_.clear();
91     want_.clear();
92 }
93 
AddTarget(const Node * target,string * err)94 bool Plan::AddTarget(const Node* target, string* err) {
95     return AddSubTarget(target, NULL, err, NULL);
96 }
97 
AddSubTarget(const Node * node,const Node * dependent,string * err,set<Edge * > * dyndep_walk)98 bool Plan::AddSubTarget(const Node* node, const Node* dependent, string* err,
99                                                 set<Edge*>* dyndep_walk) {
100     Edge* edge = node->in_edge();
101     if (!edge) {
102         // Leaf node, this can be either a regular input from the manifest
103         // (e.g. a source file), or an implicit input from a depfile or dyndep
104         // file. In the first case, a dirty flag means the file is missing,
105         // and the build should stop. In the second, do not do anything here
106         // since there is no producing edge to add to the plan.
107         if (node->dirty() && !node->generated_by_dep_loader()) {
108             string referenced;
109             if (dependent)
110                 referenced = ", needed by '" + dependent->path() + "',";
111                 *err = "'" + node->path() + "'" + referenced +
112                     " missing and no known rule to make it";
113         }
114         return false;
115     }
116 
117     if (edge->outputs_ready())
118         return false;  // Don't need to do anything.
119 
120     // If an entry in want_ does not already exist for edge, create an entry which
121     // maps to kWantNothing, indicating that we do not want to build this entry itself.
122     pair<map<Edge*, Want>::iterator, bool> want_ins =
123         want_.insert(make_pair(edge, kWantNothing));
124     Want& want = want_ins.first->second;
125 
126     if (dyndep_walk && want == kWantToFinish)
127         return false;  // Don't need to do anything with already-scheduled edge.
128 
129     // If we do need to build edge and we haven't already marked it as wanted,
130     // mark it now.
131     if (node->dirty() && want == kWantNothing) {
132         want = kWantToStart;
133         EdgeWanted(edge);
134         if (!dyndep_walk && edge->AllInputsReady())
135             ScheduleWork(want_ins.first);
136     }
137 
138     if (dyndep_walk)
139         dyndep_walk->insert(edge);
140 
141     if (!want_ins.second)
142         return true;  // We've already processed the inputs.
143 
144     for (vector<Node*>::iterator i = edge->inputs_.begin();
145             i != edge->inputs_.end(); ++i) {
146         if (!AddSubTarget(*i, node, err, dyndep_walk) && !err->empty())
147             return false;
148     }
149 
150     return true;
151 }
152 
EdgeWanted(const Edge * edge)153 void Plan::EdgeWanted(const Edge* edge) {
154     ++wanted_edges_;
155     if (!edge->is_phony()) {
156         ++command_edges_;
157         if (builder_)
158             builder_->status_->EdgeAddedToPlan(edge);
159     }
160 }
161 
FindWork()162 Edge* Plan::FindWork() {
163     if (ready_.empty())
164         return NULL;
165 
166     EdgeSet::iterator e = ready_.begin();
167     Edge* edge = *e;
168     ready_.erase(e);
169     return edge;
170 }
171 
ScheduleWork(map<Edge *,Want>::iterator want_e)172 void Plan::ScheduleWork(map<Edge*, Want>::iterator want_e) {
173     if (want_e->second == kWantToFinish) {
174         // This edge has already been scheduled.  We can get here again if an edge
175         // and one of its dependencies share an order-only input, or if a node
176         // duplicates an out edge (see https://github.com/ninja-build/ninja/pull/519).
177         // Avoid scheduling the work again.
178         return;
179     }
180     assert(want_e->second == kWantToStart);
181     want_e->second = kWantToFinish;
182 
183     Edge* edge = want_e->first;
184     Pool* pool = edge->pool();
185     if (pool->ShouldDelayEdge()) {
186         pool->DelayEdge(edge);
187         pool->RetrieveReadyEdges(&ready_);
188     } else {
189         pool->EdgeScheduled(*edge);
190         ready_.insert(edge);
191     }
192 }
193 
EdgeFinished(Edge * edge,EdgeResult result,string * err)194 bool Plan::EdgeFinished(Edge* edge, EdgeResult result, string* err) {
195     map<Edge*, Want>::iterator e = want_.find(edge);
196     assert(e != want_.end());
197     bool directly_wanted = e->second != kWantNothing;
198 
199     // See if this job frees up any delayed jobs.
200     if (directly_wanted)
201         edge->pool()->EdgeFinished(*edge);
202     edge->pool()->RetrieveReadyEdges(&ready_);
203 
204     // The rest of this function only applies to successful commands.
205     if (result != kEdgeSucceeded)
206         return true;
207 
208     if (directly_wanted)
209         --wanted_edges_;
210     want_.erase(e);
211     edge->outputs_ready_ = true;
212 
213     // Check off any nodes we were waiting for with this edge.
214     for (vector<Node*>::iterator o = edge->outputs_.begin();
215             o != edge->outputs_.end(); ++o) {
216         if (!NodeFinished(*o, err))
217             return false;
218     }
219     return true;
220 }
221 
NodeFinished(Node * node,string * err)222 bool Plan::NodeFinished(Node* node, string* err) {
223     // If this node provides dyndep info, load it now.
224     if (node->dyndep_pending()) {
225         assert(builder_ && "dyndep requires Plan to have a Builder");
226         // Load the now-clean dyndep file.  This will also update the
227         // build plan and schedule any new work that is ready.
228         return builder_->LoadDyndeps(node, err);
229     }
230 
231     // See if we we want any edges from this node.
232     for (vector<Edge*>::const_iterator oe = node->out_edges().begin();
233             oe != node->out_edges().end(); ++oe) {
234         map<Edge*, Want>::iterator want_e = want_.find(*oe);
235         if (want_e == want_.end())
236             continue;
237 
238         // See if the edge is now ready.
239         if (!EdgeMaybeReady(want_e, err))
240             return false;
241     }
242     return true;
243 }
244 
EdgeMaybeReady(map<Edge *,Want>::iterator want_e,string * err)245 bool Plan::EdgeMaybeReady(map<Edge*, Want>::iterator want_e, string* err) {
246     Edge* edge = want_e->first;
247     if (edge->AllInputsReady()) {
248         if (want_e->second != kWantNothing) {
249             ScheduleWork(want_e);
250         } else {
251             // We do not need to build this edge, but we might need to build one of
252             // its dependents.
253             if (!EdgeFinished(edge, kEdgeSucceeded, err))
254                 return false;
255         }
256     }
257     return true;
258 }
259 
CleanNode(DependencyScan * scan,Node * node,string * err)260 bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) {
261     node->set_dirty(false);
262 
263     for (vector<Edge*>::const_iterator oe = node->out_edges().begin();
264             oe != node->out_edges().end(); ++oe) {
265         // Don't process edges that we don't actually want.
266         map<Edge*, Want>::iterator want_e = want_.find(*oe);
267         if (want_e == want_.end() || want_e->second == kWantNothing)
268             continue;
269 
270         // Don't attempt to clean an edge if it failed to load deps.
271         if ((*oe)->deps_missing_)
272             continue;
273 
274         // If all non-order-only inputs for this edge are now clean,
275         // we might have changed the dirty state of the outputs.
276         vector<Node*>::iterator
277             begin = (*oe)->inputs_.begin(),
278             end = (*oe)->inputs_.end() - (*oe)->order_only_deps_;
279 #if __cplusplus < 201703L
280 #define MEM_FN mem_fun
281 #else
282 #define MEM_FN mem_fn  // mem_fun was removed in C++17.
283 #endif
284         if (find_if(begin, end, MEM_FN(&Node::dirty)) == end) {
285             // Recompute most_recent_input.
286             Node* most_recent_input = NULL;
287             for (vector<Node*>::iterator i = begin; i != end; ++i) {
288                 if (!most_recent_input || (*i)->mtime() > most_recent_input->mtime())
289                     most_recent_input = *i;
290             }
291 
292             // Now, this edge is dirty if any of the outputs are dirty.
293             // If the edge isn't dirty, clean the outputs and mark the edge as not
294             // wanted.
295             bool outputs_dirty = false;
296             if (!scan->RecomputeOutputsDirty(*oe, most_recent_input,
297                 &outputs_dirty, err)) {
298                 return false;
299             }
300             if (!outputs_dirty) {
301                 for (vector<Node*>::iterator o = (*oe)->outputs_.begin();
302                     o != (*oe)->outputs_.end(); ++o) {
303                     if (!CleanNode(scan, *o, err))
304                         return false;
305                 }
306 
307                 want_e->second = kWantNothing;
308                 --wanted_edges_;
309                 if (!(*oe)->is_phony()) {
310                     --command_edges_;
311                     if (builder_)
312                         builder_->status_->EdgeRemovedFromPlan(*oe);
313                 }
314             }
315         }
316     }
317     return true;
318 }
319 
DyndepsLoaded(DependencyScan * scan,const Node * node,const DyndepFile & ddf,string * err)320 bool Plan::DyndepsLoaded(DependencyScan* scan, const Node* node,
321                                                   const DyndepFile& ddf, string* err) {
322     // Recompute the dirty state of all our direct and indirect dependents now
323     // that our dyndep information has been loaded.
324     if (!RefreshDyndepDependents(scan, node, err))
325         return false;
326 
327     // We loaded dyndep information for those out_edges of the dyndep node that
328     // specify the node in a dyndep binding, but they may not be in the plan.
329     // Starting with those already in the plan, walk newly-reachable portion
330     // of the graph through the dyndep-discovered dependencies.
331 
332     // Find edges in the the build plan for which we have new dyndep info.
333     std::vector<DyndepFile::const_iterator> dyndep_roots;
334     for (DyndepFile::const_iterator oe = ddf.begin(); oe != ddf.end(); ++oe) {
335         Edge* edge = oe->first;
336 
337         // If the edge outputs are ready we do not need to consider it here.
338         if (edge->outputs_ready())
339             continue;
340 
341         map<Edge*, Want>::iterator want_e = want_.find(edge);
342 
343         // If the edge has not been encountered before then nothing already in the
344         // plan depends on it so we do not need to consider the edge yet either.
345         if (want_e == want_.end())
346             continue;
347 
348         // This edge is already in the plan so queue it for the walk.
349         dyndep_roots.push_back(oe);
350     }
351 
352     // Walk dyndep-discovered portion of the graph to add it to the build plan.
353     std::set<Edge*> dyndep_walk;
354     for (std::vector<DyndepFile::const_iterator>::iterator
355               oei = dyndep_roots.begin(); oei != dyndep_roots.end(); ++oei) {
356         DyndepFile::const_iterator oe = *oei;
357         for (vector<Node*>::const_iterator i = oe->second.implicit_inputs_.begin();
358                 i != oe->second.implicit_inputs_.end(); ++i) {
359             if (!AddSubTarget(*i, oe->first->outputs_[0], err, &dyndep_walk) &&
360                     !err->empty())
361                 return false;
362         }
363     }
364 
365     // Add out edges from this node that are in the plan (just as
366     // Plan::NodeFinished would have without taking the dyndep code path).
367     for (vector<Edge*>::const_iterator oe = node->out_edges().begin();
368             oe != node->out_edges().end(); ++oe) {
369         map<Edge*, Want>::iterator want_e = want_.find(*oe);
370         if (want_e == want_.end())
371             continue;
372         dyndep_walk.insert(want_e->first);
373     }
374 
375     // See if any encountered edges are now ready.
376     for (set<Edge*>::iterator wi = dyndep_walk.begin();
377             wi != dyndep_walk.end(); ++wi) {
378         map<Edge*, Want>::iterator want_e = want_.find(*wi);
379         if (want_e == want_.end())
380             continue;
381         if (!EdgeMaybeReady(want_e, err))
382             return false;
383     }
384 
385     return true;
386 }
387 
RefreshDyndepDependents(DependencyScan * scan,const Node * node,string * err)388 bool Plan::RefreshDyndepDependents(DependencyScan* scan, const Node* node,
389                                                                       string* err) {
390     // Collect the transitive closure of dependents and mark their edges
391     // as not yet visited by RecomputeDirty.
392     set<Node*> dependents;
393     UnmarkDependents(node, &dependents);
394 
395     // Update the dirty state of all dependents and check if their edges
396     // have become wanted.
397     for (set<Node*>::iterator i = dependents.begin();
398             i != dependents.end(); ++i) {
399         Node* n = *i;
400 
401         // Check if this dependent node is now dirty.  Also checks for new cycles.
402         std::vector<Node*> validation_nodes;
403         if (!scan->RecomputeDirty(n, &validation_nodes, err))
404             return false;
405 
406         // Add any validation nodes found during RecomputeDirty as new top level
407         // targets.
408         for (std::vector<Node*>::iterator v = validation_nodes.begin();
409                 v != validation_nodes.end(); ++v) {
410             if (Edge* in_edge = (*v)->in_edge()) {
411                 if (!in_edge->outputs_ready() &&
412                         !AddTarget(*v, err)) {
413                     return false;
414                 }
415             }
416         }
417         if (!n->dirty())
418             continue;
419 
420         // This edge was encountered before.  However, we may not have wanted to
421         // build it if the outputs were not known to be dirty.  With dyndep
422         // information an output is now known to be dirty, so we want the edge.
423         Edge* edge = n->in_edge();
424         assert(edge && !edge->outputs_ready());
425         map<Edge*, Want>::iterator want_e = want_.find(edge);
426         assert(want_e != want_.end());
427         if (want_e->second == kWantNothing) {
428             want_e->second = kWantToStart;
429             EdgeWanted(edge);
430         }
431     }
432     return true;
433 }
434 
UnmarkDependents(const Node * node,set<Node * > * dependents)435 void Plan::UnmarkDependents(const Node* node, set<Node*>* dependents) {
436     for (vector<Edge*>::const_iterator oe = node->out_edges().begin();
437             oe != node->out_edges().end(); ++oe) {
438         Edge* edge = *oe;
439 
440         map<Edge*, Want>::iterator want_e = want_.find(edge);
441         if (want_e == want_.end())
442             continue;
443 
444         if (edge->mark_ != Edge::VisitNone) {
445             edge->mark_ = Edge::VisitNone;
446             for (vector<Node*>::iterator o = edge->outputs_.begin();
447                     o != edge->outputs_.end(); ++o) {
448                 if (dependents->insert(*o).second)
449                     UnmarkDependents(*o, dependents);
450             }
451         }
452     }
453 }
454 
Dump() const455 void Plan::Dump() const {
456     printf("pending: %d\n", (int)want_.size());
457     for (map<Edge*, Want>::const_iterator e = want_.begin(); e != want_.end(); ++e) {
458         if (e->second != kWantNothing)
459             printf("want ");
460         e->first->Dump();
461     }
462     printf("ready: %d\n", (int)ready_.size());
463 }
464 
465 struct RealCommandRunner : public CommandRunner {
RealCommandRunnerRealCommandRunner466     explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
~RealCommandRunnerRealCommandRunner467     virtual ~RealCommandRunner() {}
468     virtual size_t CanRunMore() const;
469     virtual bool StartCommand(Edge* edge);
470     virtual bool WaitForCommand(Result* result);
471     virtual vector<Edge*> GetActiveEdges();
472     virtual void Abort();
473 
474     const BuildConfig& config_;
475     SubprocessSet subprocs_;
476     map<const Subprocess*, Edge*> subproc_to_edge_;
477 };
478 
GetActiveEdges()479 vector<Edge*> RealCommandRunner::GetActiveEdges() {
480     vector<Edge*> edges;
481     for (map<const Subprocess*, Edge*>::iterator e = subproc_to_edge_.begin();
482             e != subproc_to_edge_.end(); ++e)
483         edges.push_back(e->second);
484     return edges;
485 }
486 
Abort()487 void RealCommandRunner::Abort() {
488     subprocs_.Clear();
489 }
490 
CanRunMore() const491 size_t RealCommandRunner::CanRunMore() const {
492     size_t subproc_number =
493         subprocs_.running_.size() + subprocs_.finished_.size();
494 
495     int64_t capacity = config_.parallelism - subproc_number;
496 
497     if (config_.max_load_average > 0.0f) {
498         int load_capacity = config_.max_load_average - GetLoadAverage();
499         if (load_capacity < capacity)
500             capacity = load_capacity;
501     }
502 
503     if (capacity < 0)
504         capacity = 0;
505 
506     if (capacity == 0 && subprocs_.running_.empty())
507         // Ensure that we make progress.
508         capacity = 1;
509 
510     return capacity;
511 }
512 
StartCommand(Edge * edge)513 bool RealCommandRunner::StartCommand(Edge* edge) {
514     string command = edge->EvaluateCommand();
515     Subprocess* subproc = subprocs_.Add(command, edge->use_console());
516     if (!subproc)
517         return false;
518     subproc_to_edge_.insert(make_pair(subproc, edge));
519 
520     return true;
521 }
522 
WaitForCommand(Result * result)523 bool RealCommandRunner::WaitForCommand(Result* result) {
524     Subprocess* subproc;
525     while ((subproc = subprocs_.NextFinished()) == NULL) {
526         bool interrupted = subprocs_.DoWork();
527         if (interrupted)
528             return false;
529     }
530 
531     result->status = subproc->Finish();
532     result->output = subproc->GetOutput();
533 
534     map<const Subprocess*, Edge*>::iterator e = subproc_to_edge_.find(subproc);
535     result->edge = e->second;
536     subproc_to_edge_.erase(e);
537 
538     delete subproc;
539     return true;
540 }
541 
Builder(State * state,const BuildConfig & config,BuildLog * build_log,DepsLog * deps_log,DiskInterface * disk_interface,Status * status,int64_t start_time_millis)542 Builder::Builder(State* state, const BuildConfig& config,
543                                   BuildLog* build_log, DepsLog* deps_log,
544                                   DiskInterface* disk_interface, Status *status,
545                                   int64_t start_time_millis)
546         : state_(state), config_(config), plan_(this), status_(status),
547             start_time_millis_(start_time_millis), disk_interface_(disk_interface),
548             scan_(state, build_log, deps_log, disk_interface,
549                 &config_.depfile_parser_options) {
550     lock_file_path_ = ".ninja_lock";
551     string build_dir = state_->bindings_.LookupVariable("builddir");
552     if (!build_dir.empty())
553         lock_file_path_ = build_dir + "/" + lock_file_path_;
554 }
555 
~Builder()556 Builder::~Builder() {
557     Cleanup();
558 }
559 
Cleanup()560 void Builder::Cleanup() {
561     if (command_runner_.get()) {
562         vector<Edge*> active_edges = command_runner_->GetActiveEdges();
563         command_runner_->Abort();
564 
565         for (vector<Edge*>::iterator e = active_edges.begin();
566                 e != active_edges.end(); ++e) {
567             string depfile = (*e)->GetUnescapedDepfile();
568             for (vector<Node*>::iterator o = (*e)->outputs_.begin();
569                     o != (*e)->outputs_.end(); ++o) {
570                 // Only delete this output if it was actually modified.  This is
571                 // important for things like the generator where we don't want to
572                 // delete the manifest file if we can avoid it.  But if the rule
573                 // uses a depfile, always delete.  (Consider the case where we
574                 // need to rebuild an output because of a modified header file
575                 // mentioned in a depfile, and the command touches its depfile
576                 // but is interrupted before it touches its output file.)
577                 string err;
578                 TimeStamp new_mtime = disk_interface_->Stat((*o)->path(), &err);
579                 if (new_mtime == -1)  // Log and ignore Stat() errors.
580                     status_->Error("%s", err.c_str());
581                 if (!depfile.empty() || (*o)->mtime() != new_mtime)
582                     disk_interface_->RemoveFile((*o)->path());
583             }
584             if (!depfile.empty())
585                 disk_interface_->RemoveFile(depfile);
586         }
587     }
588 
589     string err;
590     if (disk_interface_->Stat(lock_file_path_, &err) > 0)
591         disk_interface_->RemoveFile(lock_file_path_);
592 }
593 
AddTarget(const string & name,string * err)594 Node* Builder::AddTarget(const string& name, string* err) {
595     Node* node = state_->LookupNode(name);
596     if (!node) {
597         *err = "unknown target: '" + name + "'";
598         return NULL;
599     }
600     if (!AddTarget(node, err))
601         return NULL;
602     return node;
603 }
604 
AddTarget(Node * target,string * err)605 bool Builder::AddTarget(Node* target, string* err) {
606     std::vector<Node*> validation_nodes;
607     if (!scan_.RecomputeDirty(target, &validation_nodes, err))
608         return false;
609 
610     Edge* in_edge = target->in_edge();
611     if (!in_edge || !in_edge->outputs_ready()) {
612         if (!plan_.AddTarget(target, err)) {
613             return false;
614         }
615     }
616 
617     // Also add any validation nodes found during RecomputeDirty as top level
618     // targets.
619     for (std::vector<Node*>::iterator n = validation_nodes.begin();
620             n != validation_nodes.end(); ++n) {
621         if (Edge* validation_in_edge = (*n)->in_edge()) {
622             if (!validation_in_edge->outputs_ready() &&
623                 !plan_.AddTarget(*n, err)) {
624                 return false;
625             }
626         }
627     }
628 
629     return true;
630 }
631 
AlreadyUpToDate() const632 bool Builder::AlreadyUpToDate() const {
633     return !plan_.more_to_do();
634 }
635 
Build(string * err)636 bool Builder::Build(string* err) {
637     assert(!AlreadyUpToDate());
638 
639     int pending_commands = 0;
640     int failures_allowed = config_.failures_allowed;
641 
642     // Set up the command runner if we haven't done so already.
643     if (!command_runner_.get()) {
644         if (config_.dry_run)
645             command_runner_.reset(new DryRunCommandRunner);
646         else
647             command_runner_.reset(new RealCommandRunner(config_));
648     }
649 
650     // We are about to start the build process.
651     status_->BuildStarted();
652 
653     // This main loop runs the entire build process.
654     // It is structured like this:
655     // First, we attempt to start as many commands as allowed by the
656     // command runner.
657     // Second, we attempt to wait for / reap the next finished command.
658     while (plan_.more_to_do()) {
659         // See if we can start any more commands.
660         if (failures_allowed) {
661             size_t capacity = command_runner_->CanRunMore();
662             while (capacity > 0) {
663                 Edge* edge = plan_.FindWork();
664                 if (!edge)
665                     break;
666 
667                 if (edge->GetBindingBool("generator")) {
668                     scan_.build_log()->Close();
669                 }
670 
671                 if (!StartEdge(edge, err)) {
672                     Cleanup();
673                     status_->BuildFinished();
674                     return false;
675                 }
676 
677                 if (edge->is_phony()) {
678                     if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
679                         Cleanup();
680                         status_->BuildFinished();
681                         return false;
682                     }
683                 } else {
684                     ++pending_commands;
685 
686                     --capacity;
687 
688                     // Re-evaluate capacity.
689                     size_t current_capacity = command_runner_->CanRunMore();
690                     if (current_capacity < capacity)
691                         capacity = current_capacity;
692                 }
693             }
694 
695             // We are finished with all work items and have no pending
696             // commands. Therefore, break out of the main loop.
697             if (pending_commands == 0 && !plan_.more_to_do()) break;
698         }
699 
700         // See if we can reap any finished commands.
701         if (pending_commands) {
702             CommandRunner::Result result;
703             if (!command_runner_->WaitForCommand(&result) ||
704                     result.status == ExitInterrupted) {
705                 Cleanup();
706                 status_->BuildFinished();
707                 *err = "interrupted by user";
708                 return false;
709             }
710 
711             --pending_commands;
712             if (!FinishCommand(&result, err)) {
713                 Cleanup();
714                 status_->BuildFinished();
715                 return false;
716             }
717 
718             if (!result.success()) {
719                 if (failures_allowed)
720                     failures_allowed--;
721             }
722 
723             // We made some progress; start the main loop over.
724             continue;
725         }
726 
727         // If we get here, we cannot make any more progress.
728         status_->BuildFinished();
729         if (failures_allowed == 0) {
730             if (config_.failures_allowed > 1)
731                 *err = "subcommands failed";
732             else
733                 *err = "subcommand failed";
734         } else if (failures_allowed < config_.failures_allowed)
735             *err = "cannot make progress due to previous errors";
736         else
737             *err = "stuck [this is a bug]";
738 
739         return false;
740     }
741 
742     status_->BuildFinished();
743     return true;
744 }
745 
Trim(std::string & s)746 static std::string &Trim(std::string &s)
747 {
748     if (s.empty()) {
749         return s;
750     }
751     size_t start = s.find_first_not_of(" \t\r\n");
752     if (start == std::string::npos) {
753         s.clear();
754         return s;
755     }
756     s.erase(0, start);
757 
758     size_t end = s.find_last_not_of(" \t\r\n");
759     if (end != std::string::npos) {
760         s.erase(end + 1);
761     }
762     return s;
763 }
764 
SplitStringBySpace(std::string content)765 static std::vector<std::string> SplitStringBySpace(std::string content)
766 {
767     std::string space_delimiter = " ";
768     std::vector<std::string> words{};
769     size_t pos = 0;
770     std::string temp_content = content;
771     while ((pos = temp_content.find(space_delimiter)) != string::npos) {
772         std::string sub_str = temp_content.substr(0, pos);
773         std::string tmp = Trim(sub_str);
774         if (!tmp.empty()) {
775             words.push_back(tmp);
776         }
777         temp_content = temp_content.substr(pos + 1);
778     }
779     std::string tmp_last = Trim(temp_content);
780     if (!tmp_last.empty()) {
781         words.push_back(tmp_last);
782     }
783     return words;
784 }
785 
SplicingWholeContent(std::string content,std::string whole_content,bool is_whole_archive)786 std::string SplicingWholeContent(std::string content, std::string whole_content, bool is_whole_archive) {
787     if (whole_content.empty()) {
788         return content;
789     }
790 
791     std::string temp_content = content;
792     if (is_whole_archive) {
793         temp_content += " -Wl,--whole-archive";
794     }
795 
796     std::vector<std::string> whole_list = SplitStringBySpace(whole_content);
797     std::vector<std::string> content_list = SplitStringBySpace(temp_content);
798     std::set<std::string> processed_words;
799     for (const std::string &word : whole_list) {
800         auto it = std::find_if(content_list.begin(), content_list.end(), [&](const std::string& s) {
801             return s.find(word) != std::string::npos;
802         });
803         if (it != content_list.end() && processed_words.find(*it) == processed_words.end()) {
804             std::string element = *it;
805             content_list.erase(it);
806             content_list.push_back(element);
807             processed_words.insert(element);
808         }
809     }
810 
811     std::string result = "";
812     for (size_t i = 0; i < content_list.size(); ++i) {
813         result += content_list[i];
814         if (i != content_list.size() - 1) {
815             result += " ";
816         }
817     }
818     return result;
819 }
820 
GetContent(Edge * edge)821 std::string Builder::GetContent(Edge* edge)
822 {
823     std::string content = edge->GetBinding("rspfile_content");
824     std::string toolchain_whole_status =  edge->env_->LookupVariable("toolchain_whole_status");
825 
826     if (toolchain_whole_status == "0") {
827         return SplicingWholeContent(content, edge->env_->LookupVariable("whole-archive"), true);
828     } else if (toolchain_whole_status == "1") {
829         return SplicingWholeContent(content, edge->env_->LookupVariable("no-whole-archive"), false);
830     } else {
831         return content;
832     }
833 }
834 
StartEdge(Edge * edge,string * err)835 bool Builder::StartEdge(Edge* edge, string* err) {
836     METRIC_RECORD("StartEdge");
837     if (edge->is_phony())
838         return true;
839 
840     int64_t start_time_millis = GetTimeMillis() - start_time_millis_;
841     running_edges_.insert(make_pair(edge, start_time_millis));
842 
843     status_->BuildEdgeStarted(edge, start_time_millis);
844 
845     TimeStamp build_start = -1;
846 
847     // Create directories necessary for outputs and remember the current
848     // filesystem mtime to record later
849     // XXX: this will block; do we care?
850     for (vector<Node*>::iterator o = edge->outputs_.begin();
851             o != edge->outputs_.end(); ++o) {
852         if (!disk_interface_->MakeDirs((*o)->path()))
853             return false;
854         if (build_start == -1) {
855             disk_interface_->WriteFile(lock_file_path_, "");
856             build_start = disk_interface_->Stat(lock_file_path_, err);
857             if (build_start == -1)
858                 build_start = 0;
859         }
860     }
861 
862     edge->command_start_time_ = build_start;
863 
864     // Create response file, if needed
865     // XXX: this may also block; do we care?
866     string rspfile = edge->GetUnescapedRspfile();
867     if (!rspfile.empty()) {
868         string content = GetContent(edge);
869         if (!disk_interface_->WriteFile(rspfile, content))
870             return false;
871     }
872 
873     // start command computing and run it
874     if (!command_runner_->StartCommand(edge)) {
875         err->assign("command '" + edge->EvaluateCommand() + "' failed.");
876         return false;
877     }
878 
879     return true;
880 }
881 
FinishCommand(CommandRunner::Result * result,string * err)882 bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
883     METRIC_RECORD("FinishCommand");
884 
885     Edge* edge = result->edge;
886 
887     // First try to extract dependencies from the result, if any.
888     // This must happen first as it filters the command output (we want
889     // to filter /showIncludes output, even on compile failure) and
890     // extraction itself can fail, which makes the command fail from a
891     // build perspective.
892     vector<Node*> deps_nodes;
893     string deps_type = edge->GetBinding("deps");
894     const string deps_prefix = edge->GetBinding("msvc_deps_prefix");
895     if (!deps_type.empty()) {
896         string extract_err;
897         if (!ExtractDeps(result, deps_type, deps_prefix, &deps_nodes,
898             &extract_err) && result->success()) {
899             if (!result->output.empty())
900                 result->output.append("\n");
901             result->output.append(extract_err);
902             result->status = ExitFailure;
903         }
904     }
905 
906     int64_t start_time_millis, end_time_millis;
907     RunningEdgeMap::iterator it = running_edges_.find(edge);
908     start_time_millis = it->second;
909     end_time_millis = GetTimeMillis() - start_time_millis_;
910     running_edges_.erase(it);
911 
912     status_->BuildEdgeFinished(edge, start_time_millis, end_time_millis,
913         result->success(), result->output);
914 
915     // The rest of this function only applies to successful commands.
916     if (!result->success()) {
917         return plan_.EdgeFinished(edge, Plan::kEdgeFailed, err);
918     }
919 
920     // Restat the edge outputs
921     TimeStamp record_mtime = 0;
922     if (!config_.dry_run) {
923         const bool restat = edge->GetBindingBool("restat");
924         const bool generator = edge->GetBindingBool("generator");
925         bool node_cleaned = false;
926         record_mtime = edge->command_start_time_;
927 
928         // restat and generator rules must restat the outputs after the build
929         // has finished. if record_mtime == 0, then there was an error while
930         // attempting to touch/stat the temp file when the edge started and
931         // we should fall back to recording the outputs' current mtime in the
932         // log.
933         if (record_mtime == 0 || restat || generator) {
934             for (vector<Node*>::iterator o = edge->outputs_.begin();
935                     o != edge->outputs_.end(); ++o) {
936                 TimeStamp new_mtime = disk_interface_->Stat((*o)->path(), err);
937                 if (new_mtime == -1)
938                     return false;
939                 if (new_mtime > record_mtime)
940                     record_mtime = new_mtime;
941                 if ((*o)->mtime() == new_mtime && restat) {
942                     // The rule command did not change the output.  Propagate the clean
943                     // state through the build graph.
944                     // Note that this also applies to nonexistent outputs (mtime == 0).
945                     if (!plan_.CleanNode(&scan_, *o, err))
946                         return false;
947                     node_cleaned = true;
948                 }
949             }
950         }
951         if (node_cleaned) {
952             record_mtime = edge->command_start_time_;
953         }
954     }
955 
956     if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err))
957         return false;
958 
959     // Delete any left over response file.
960     string rspfile = edge->GetUnescapedRspfile();
961     if (!rspfile.empty() && !g_keep_rsp)
962         disk_interface_->RemoveFile(rspfile);
963 
964     if (scan_.build_log()) {
965         if (!scan_.build_log()->RecordCommand(edge, start_time_millis,
966             end_time_millis, record_mtime)) {
967             *err = string("Error writing to build log: ") + strerror(errno);
968             return false;
969         }
970     }
971 
972     if (!deps_type.empty() && !config_.dry_run) {
973         assert(!edge->outputs_.empty() && "should have been rejected by parser");
974         for (std::vector<Node*>::const_iterator o = edge->outputs_.begin();
975                 o != edge->outputs_.end(); ++o) {
976             TimeStamp deps_mtime = disk_interface_->Stat((*o)->path(), err);
977             if (deps_mtime == -1)
978                 return false;
979             if (!scan_.deps_log()->RecordDeps(*o, deps_mtime, deps_nodes)) {
980                 *err = std::string("Error writing to deps log: ") + strerror(errno);
981                 return false;
982             }
983         }
984     }
985     return true;
986 }
987 
ExtractDeps(CommandRunner::Result * result,const string & deps_type,const string & deps_prefix,vector<Node * > * deps_nodes,string * err)988 bool Builder::ExtractDeps(CommandRunner::Result* result,
989                                                     const string& deps_type,
990                                                     const string& deps_prefix,
991                                                     vector<Node*>* deps_nodes,
992                                                     string* err) {
993     if (deps_type == "msvc") {
994         CLParser parser;
995         string output;
996         if (!parser.Parse(result->output, deps_prefix, &output, err))
997             return false;
998         result->output = output;
999         for (set<string>::iterator i = parser.includes_.begin();
1000                 i != parser.includes_.end(); ++i) {
1001             // ~0 is assuming that with MSVC-parsed headers, it's ok to always make
1002             // all backslashes (as some of the slashes will certainly be backslashes
1003             // anyway). This could be fixed if necessary with some additional
1004             // complexity in IncludesNormalize::Relativize.
1005             deps_nodes->push_back(state_->GetNode(*i, ~0u));
1006         }
1007     } else if (deps_type == "gcc") {
1008         string depfile = result->edge->GetUnescapedDepfile();
1009         if (depfile.empty()) {
1010             *err = string("edge with deps=gcc but no depfile makes no sense");
1011             return false;
1012         }
1013 
1014         // Read depfile content.  Treat a missing depfile as empty.
1015         string content;
1016         switch (disk_interface_->ReadFile(depfile, &content, err)) {
1017         case DiskInterface::Okay:
1018             break;
1019         case DiskInterface::NotFound:
1020             err->clear();
1021             break;
1022         case DiskInterface::OtherError:
1023             return false;
1024         }
1025         if (content.empty())
1026             return true;
1027 
1028         DepfileParser deps(config_.depfile_parser_options);
1029         if (!deps.Parse(&content, err))
1030             return false;
1031 
1032         // XXX check depfile matches expected output.
1033         deps_nodes->reserve(deps.ins_.size());
1034         for (vector<StringPiece>::iterator i = deps.ins_.begin();
1035                 i != deps.ins_.end(); ++i) {
1036             uint64_t slash_bits;
1037             CanonicalizePath(const_cast<char*>(i->str_), &i->len_, &slash_bits);
1038             deps_nodes->push_back(state_->GetNode(*i, slash_bits));
1039         }
1040 
1041         if (!g_keep_depfile) {
1042             if (disk_interface_->RemoveFile(depfile) < 0) {
1043                 *err = string("deleting depfile: ") + strerror(errno) + string("\n");
1044                 return false;
1045             }
1046         }
1047     } else {
1048         Fatal("unknown deps type '%s'", deps_type.c_str());
1049     }
1050 
1051     return true;
1052 }
1053 
LoadDyndeps(Node * node,string * err)1054 bool Builder::LoadDyndeps(Node* node, string* err) {
1055     status_->BuildLoadDyndeps();
1056 
1057     // Load the dyndep information provided by this node.
1058     DyndepFile ddf;
1059     if (!scan_.LoadDyndeps(node, &ddf, err))
1060         return false;
1061 
1062     // Update the build plan to account for dyndep modifications to the graph.
1063     if (!plan_.DyndepsLoaded(&scan_, node, ddf, err))
1064         return false;
1065 
1066     return true;
1067 }
1068