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 #ifndef NINJA_BUILD_H_
16 #define NINJA_BUILD_H_
17 
18 #include <cstdio>
19 #include <map>
20 #include <memory>
21 #include <queue>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 #include "depfile_parser.h"
27 #include "graph.h"  // XXX needed for DependencyScan; should rearrange.
28 #include "exit_status.h"
29 #include "line_printer.h"
30 #include "metrics.h"
31 #include "util.h"  // int64_t
32 
33 struct BuildLog;
34 struct BuildStatus;
35 struct Builder;
36 struct DiskInterface;
37 struct Edge;
38 struct Node;
39 struct State;
40 
41 /// Plan stores the state of a build plan: what we intend to build,
42 /// which steps we're ready to execute.
43 struct Plan {
44   Plan(Builder* builder = NULL);
45 
46   /// Add a target to our plan (including all its dependencies).
47   /// Returns false if we don't need to build this target; may
48   /// fill in |err| with an error message if there's a problem.
49   bool AddTarget(const Node* node, std::string* err);
50 
51   // Pop a ready edge off the queue of edges to build.
52   // Returns NULL if there's no work to do.
53   Edge* FindWork();
54 
55   /// Returns true if there's more work to be done.
more_to_doPlan56   bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
57 
58   /// Dumps the current state of the plan.
59   void Dump() const;
60 
61   enum EdgeResult {
62     kEdgeFailed,
63     kEdgeSucceeded
64   };
65 
66   /// Mark an edge as done building (whether it succeeded or failed).
67   /// If any of the edge's outputs are dyndep bindings of their dependents,
68   /// this loads dynamic dependencies from the nodes' paths.
69   /// Returns 'false' if loading dyndep info fails and 'true' otherwise.
70   bool EdgeFinished(Edge* edge, EdgeResult result, std::string* err);
71 
72   /// Clean the given node during the build.
73   /// Return false on error.
74   bool CleanNode(DependencyScan* scan, Node* node, std::string* err);
75 
76   /// Number of edges with commands to run.
command_edge_countPlan77   int command_edge_count() const { return command_edges_; }
78 
79   /// Reset state.  Clears want and ready sets.
80   void Reset();
81 
82   /// Update the build plan to account for modifications made to the graph
83   /// by information loaded from a dyndep file.
84   bool DyndepsLoaded(DependencyScan* scan, const Node* node,
85                      const DyndepFile& ddf, std::string* err);
86 private:
87   bool RefreshDyndepDependents(DependencyScan* scan, const Node* node, std::string* err);
88   void UnmarkDependents(const Node* node, std::set<Node*>* dependents);
89   bool AddSubTarget(const Node* node, const Node* dependent, std::string* err,
90                     std::set<Edge*>* dyndep_walk);
91 
92   /// Update plan with knowledge that the given node is up to date.
93   /// If the node is a dyndep binding on any of its dependents, this
94   /// loads dynamic dependencies from the node's path.
95   /// Returns 'false' if loading dyndep info fails and 'true' otherwise.
96   bool NodeFinished(Node* node, std::string* err);
97 
98   /// Enumerate possible steps we want for an edge.
99   enum Want
100   {
101     /// We do not want to build the edge, but we might want to build one of
102     /// its dependents.
103     kWantNothing,
104     /// We want to build the edge, but have not yet scheduled it.
105     kWantToStart,
106     /// We want to build the edge, have scheduled it, and are waiting
107     /// for it to complete.
108     kWantToFinish
109   };
110 
111   void EdgeWanted(const Edge* edge);
112   bool EdgeMaybeReady(std::map<Edge*, Want>::iterator want_e, std::string* err);
113 
114   /// Submits a ready edge as a candidate for execution.
115   /// The edge may be delayed from running, for example if it's a member of a
116   /// currently-full pool.
117   void ScheduleWork(std::map<Edge*, Want>::iterator want_e);
118 
119   /// Keep track of which edges we want to build in this plan.  If this map does
120   /// not contain an entry for an edge, we do not want to build the entry or its
121   /// dependents.  If it does contain an entry, the enumeration indicates what
122   /// we want for the edge.
123   std::map<Edge*, Want> want_;
124 
125   std::set<Edge*> ready_;
126 
127   Builder* builder_;
128 
129   /// Total number of edges that have commands (not phony).
130   int command_edges_;
131 
132   /// Total remaining number of wanted edges.
133   int wanted_edges_;
134 };
135 
136 /// CommandRunner is an interface that wraps running the build
137 /// subcommands.  This allows tests to abstract out running commands.
138 /// RealCommandRunner is an implementation that actually runs commands.
139 struct CommandRunner {
~CommandRunnerCommandRunner140   virtual ~CommandRunner() {}
141   virtual bool CanRunMore() const = 0;
142   virtual bool StartCommand(Edge* edge) = 0;
143 
144   /// The result of waiting for a command.
145   struct Result {
ResultCommandRunner::Result146     Result() : edge(NULL) {}
147     Edge* edge;
148     ExitStatus status;
149     std::string output;
successCommandRunner::Result150     bool success() const { return status == ExitSuccess; }
151   };
152   /// Wait for a command to complete, or return false if interrupted.
153   virtual bool WaitForCommand(Result* result) = 0;
154 
GetActiveEdgesCommandRunner155   virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
AbortCommandRunner156   virtual void Abort() {}
157 };
158 
159 /// Options (e.g. verbosity, parallelism) passed to a build.
160 struct BuildConfig {
BuildConfigBuildConfig161   BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
162                   failures_allowed(1), max_load_average(-0.0f) {}
163 
164   enum Verbosity {
165     NORMAL,
166     QUIET,  // No output -- used when testing.
167     VERBOSE
168   };
169   Verbosity verbosity;
170   bool dry_run;
171   int parallelism;
172   int failures_allowed;
173   /// The maximum load average we must not exceed. A negative value
174   /// means that we do not have any limit.
175   double max_load_average;
176   DepfileParserOptions depfile_parser_options;
177 };
178 
179 /// Builder wraps the build process: starting commands, updating status.
180 struct Builder {
181   Builder(State* state, const BuildConfig& config,
182           BuildLog* build_log, DepsLog* deps_log,
183           DiskInterface* disk_interface);
184   ~Builder();
185 
186   /// Clean up after interrupted commands by deleting output files.
187   void Cleanup();
188 
189   Node* AddTarget(const std::string& name, std::string* err);
190 
191   /// Add a target to the build, scanning dependencies.
192   /// @return false on error.
193   bool AddTarget(Node* target, std::string* err);
194 
195   /// Returns true if the build targets are already up to date.
196   bool AlreadyUpToDate() const;
197 
198   /// Run the build.  Returns false on error.
199   /// It is an error to call this function when AlreadyUpToDate() is true.
200   bool Build(std::string* err);
201 
202   bool StartEdge(Edge* edge, std::string* err);
203 
204   /// Update status ninja logs following a command termination.
205   /// @return false if the build can not proceed further due to a fatal error.
206   bool FinishCommand(CommandRunner::Result* result, std::string* err);
207 
208   /// Used for tests.
SetBuildLogBuilder209   void SetBuildLog(BuildLog* log) {
210     scan_.set_build_log(log);
211   }
212 
213   /// Load the dyndep information provided by the given node.
214   bool LoadDyndeps(Node* node, std::string* err);
215 
216   State* state_;
217   const BuildConfig& config_;
218   Plan plan_;
219 #if __cplusplus < 201703L
220   std::auto_ptr<CommandRunner> command_runner_;
221 #else
222   std::unique_ptr<CommandRunner> command_runner_;  // auto_ptr was removed in C++17.
223 #endif
224   BuildStatus* status_;
225 
226  private:
227   bool ExtractDeps(CommandRunner::Result* result, const std::string& deps_type,
228                    const std::string& deps_prefix,
229                    std::vector<Node*>* deps_nodes, std::string* err);
230 
231   DiskInterface* disk_interface_;
232   DependencyScan scan_;
233 
234   // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
235   Builder(const Builder &other);        // DO NOT IMPLEMENT
236   void operator=(const Builder &other); // DO NOT IMPLEMENT
237 };
238 
239 /// Tracks the status of a build: completion fraction, printing updates.
240 struct BuildStatus {
241   explicit BuildStatus(const BuildConfig& config);
242   void PlanHasTotalEdges(int total);
243   void BuildEdgeStarted(const Edge* edge);
244   void BuildEdgeFinished(Edge* edge, bool success, const std::string& output,
245                          int* start_time, int* end_time);
246   void BuildLoadDyndeps();
247   void BuildStarted();
248   void BuildFinished();
249 
250   enum EdgeStatus {
251     kEdgeStarted,
252     kEdgeFinished,
253   };
254 
255   /// Format the progress status string by replacing the placeholders.
256   /// See the user manual for more information about the available
257   /// placeholders.
258   /// @param progress_status_format The format of the progress status.
259   /// @param status The status of the edge.
260   std::string FormatProgressStatus(const char* progress_status_format,
261                                    EdgeStatus status) const;
262 
263  private:
264   void PrintStatus(const Edge* edge, EdgeStatus status);
265 
266   const BuildConfig& config_;
267 
268   /// Time the build started.
269   int64_t start_time_millis_;
270 
271   int started_edges_, finished_edges_, total_edges_;
272 
273   /// Map of running edge to time the edge started running.
274   typedef std::map<const Edge*, int> RunningEdgeMap;
275   RunningEdgeMap running_edges_;
276 
277   /// Prints progress output.
278   LinePrinter printer_;
279 
280   /// The custom progress status format to use.
281   const char* progress_status_format_;
282 
283   template<size_t S>
SnprintfRateBuildStatus284   void SnprintfRate(double rate, char(&buf)[S], const char* format) const {
285     if (rate == -1)
286       snprintf(buf, S, "?");
287     else
288       snprintf(buf, S, format, rate);
289   }
290 
291   struct RateInfo {
RateInfoBuildStatus::RateInfo292     RateInfo() : rate_(-1) {}
293 
RestartBuildStatus::RateInfo294     void Restart() { stopwatch_.Restart(); }
ElapsedBuildStatus::RateInfo295     double Elapsed() const { return stopwatch_.Elapsed(); }
rateBuildStatus::RateInfo296     double rate() { return rate_; }
297 
UpdateRateBuildStatus::RateInfo298     void UpdateRate(int edges) {
299       if (edges && stopwatch_.Elapsed())
300         rate_ = edges / stopwatch_.Elapsed();
301     }
302 
303   private:
304     double rate_;
305     Stopwatch stopwatch_;
306   };
307 
308   struct SlidingRateInfo {
SlidingRateInfoBuildStatus::SlidingRateInfo309     SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
310 
RestartBuildStatus::SlidingRateInfo311     void Restart() { stopwatch_.Restart(); }
rateBuildStatus::SlidingRateInfo312     double rate() { return rate_; }
313 
UpdateRateBuildStatus::SlidingRateInfo314     void UpdateRate(int update_hint) {
315       if (update_hint == last_update_)
316         return;
317       last_update_ = update_hint;
318 
319       if (times_.size() == N)
320         times_.pop();
321       times_.push(stopwatch_.Elapsed());
322       if (times_.back() != times_.front())
323         rate_ = times_.size() / (times_.back() - times_.front());
324     }
325 
326   private:
327     double rate_;
328     Stopwatch stopwatch_;
329     const size_t N;
330     std::queue<double> times_;
331     int last_update_;
332   };
333 
334   mutable RateInfo overall_rate_;
335   mutable SlidingRateInfo current_rate_;
336 };
337 
338 #endif  // NINJA_BUILD_H_
339