Ninja
build.h
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 #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.
56  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 {
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.
77  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.
104  /// We want to build the edge, but have not yet scheduled it.
106  /// We want to build the edge, have scheduled it, and are waiting
107  /// for it to complete.
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 
128 
129  /// Total number of edges that have commands (not phony).
131 
132  /// Total remaining number of 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.
140  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 {
146  Result() : edge(NULL) {}
149  std::string output;
150  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 
155  virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
156  virtual void Abort() {}
157 };
158 
159 /// Options (e.g. verbosity, parallelism) passed to a build.
160 struct BuildConfig {
162  failures_allowed(1), max_load_average(-0.0f) {}
163 
164  enum Verbosity {
166  QUIET, // No output -- used when testing.
168  };
170  bool dry_run;
173  /// The maximum load average we must not exceed. A negative value
174  /// means that we do not have any limit.
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.
209  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 
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
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 
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 {
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 
267 
268  /// Time the build started.
270 
272 
273  /// Map of running edge to time the edge started running.
274  typedef std::map<const Edge*, int> RunningEdgeMap;
276 
277  /// Prints progress output.
279 
280  /// The custom progress status format to use.
282 
283  template<size_t S>
284  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 {
292  RateInfo() : rate_(-1) {}
293 
294  void Restart() { stopwatch_.Restart(); }
295  double Elapsed() const { return stopwatch_.Elapsed(); }
296  double rate() { return rate_; }
297 
298  void UpdateRate(int edges) {
299  if (edges && stopwatch_.Elapsed())
300  rate_ = edges / stopwatch_.Elapsed();
301  }
302 
303  private:
304  double rate_;
306  };
307 
309  SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
310 
311  void Restart() { stopwatch_.Restart(); }
312  double rate() { return rate_; }
313 
314  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_;
329  const size_t N;
330  std::queue<double> times_;
332  };
333 
336 };
337 
338 #endif // NINJA_BUILD_H_
Stopwatch stopwatch_
Definition: build.h:305
bool Build(std::string *err)
Run the build.
Definition: build.cc:804
bool RefreshDyndepDependents(DependencyScan *scan, const Node *node, std::string *err)
Definition: build.cc:603
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:139
std::auto_ptr< CommandRunner > command_runner_
Definition: build.h:220
Verbosity verbosity
Definition: build.h:169
We do not want to build the edge, but we might want to build one of its dependents.
Definition: build.h:103
BuildStatus(const BuildConfig &config)
Definition: build.cc:81
void BuildLoadDyndeps()
Definition: build.cc:180
RateInfo overall_rate_
Definition: build.h:334
Builder * builder_
Definition: build.h:127
Store data loaded from one dyndep file.
Definition: dyndep.h:40
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:175
Plan stores the state of a build plan: what we intend to build, which steps we&#39;re ready to execute...
Definition: build.h:43
BuildConfig()
Definition: build.h:161
SlidingRateInfo current_rate_
Definition: build.h:335
void BuildEdgeFinished(Edge *edge, bool success, const std::string &output, int *start_time, int *end_time)
Definition: build.cc:111
void UpdateRate(int edges)
Definition: build.h:298
The result of waiting for a command.
Definition: build.h:145
std::set< Edge * > ready_
Definition: build.h:125
std::string FormatProgressStatus(const char *progress_status_format, EdgeStatus status) const
Format the progress status string by replacing the placeholders.
Definition: build.cc:204
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:37
Edge * FindWork()
Definition: build.cc:381
virtual bool CanRunMore() const =0
double Elapsed() const
Definition: build.h:295
bool DyndepsLoaded(DependencyScan *scan, const Node *node, const DyndepFile &ddf, std::string *err)
Update the build plan to account for modifications made to the graph by information loaded from a dyn...
Definition: build.cc:535
State * state_
Definition: build.h:216
std::string output
Definition: build.h:149
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:217
int finished_edges_
Definition: build.h:271
Plan(Builder *builder=NULL)
Definition: build.cc:308
const BuildConfig & config_
Definition: build.h:266
bool StartEdge(Edge *edge, std::string *err)
Definition: build.cc:902
std::map< const Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:274
void Dump() const
Dumps the current state of the plan.
Definition: build.cc:657
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:77
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:139
void UpdateRate(int update_hint)
Definition: build.h:314
virtual void Abort()
Definition: build.h:156
Store a log of every command ran for every build.
Definition: build_log.h:43
int started_edges_
Definition: build.h:271
virtual std::vector< Edge * > GetActiveEdges()
Definition: build.h:155
DiskInterface * disk_interface_
Definition: build.h:231
std::map< Edge *, Want > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:123
void ScheduleWork(std::map< Edge *, Want >::iterator want_e)
Submits a ready edge as a candidate for execution.
Definition: build.cc:390
bool AddSubTarget(const Node *node, const Node *dependent, std::string *err, std::set< Edge *> *dyndep_walk)
Definition: build.cc:325
Want
Enumerate possible steps we want for an edge.
Definition: build.h:99
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:28
void operator=(const Builder &other)
int parallelism
Definition: build.h:171
int failures_allowed
Definition: build.h:172
Builder(State *state, const BuildConfig &config, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface)
Definition: build.cc:730
~Builder()
Definition: build.cc:740
void BuildStarted()
Definition: build.cc:194
void Reset()
Reset state. Clears want and ready sets.
Definition: build.cc:314
bool ExtractDeps(CommandRunner::Result *result, const std::string &deps_type, const std::string &deps_prefix, std::vector< Node *> *deps_nodes, std::string *err)
Definition: build.cc:1054
bool AddTarget(const Node *node, std::string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:321
Node * AddTarget(const std::string &name, std::string *err)
int64_t start_time_millis_
Time the build started.
Definition: build.h:269
void PrintStatus(const Edge *edge, EdgeStatus status)
Definition: build.cc:292
ExitStatus
Definition: exit_status.h:18
int total_edges_
Definition: build.h:271
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:133
ExitStatus status
Definition: build.h:148
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:744
void set_build_log(BuildLog *log)
Definition: graph.h:291
bool EdgeMaybeReady(std::map< Edge *, Want >::iterator want_e, std::string *err)
Definition: build.cc:463
We want to build the edge, but have not yet scheduled it.
Definition: build.h:105
std::queue< double > times_
Definition: build.h:330
double Elapsed() const
Seconds since Restart() call.
Definition: metrics.h:71
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:209
Builder wraps the build process: starting commands, updating status.
Definition: build.h:180
bool LoadDyndeps(Node *node, std::string *err)
Load the dyndep information provided by the given node.
Definition: build.cc:1122
bool EdgeFinished(Edge *edge, EdgeResult result, std::string *err)
Mark an edge as done building (whether it succeeded or failed).
Definition: build.cc:412
void PlanHasTotalEdges(int total)
Definition: build.cc:94
EdgeResult
Definition: build.h:61
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:240
void SnprintfRate(double rate, char(&buf)[S], const char *format) const
Definition: build.h:284
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:281
bool NodeFinished(Node *node, std::string *err)
Update plan with knowledge that the given node is up to date.
Definition: build.cc:440
Plan plan_
Definition: build.h:218
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:267
void BuildFinished()
Definition: build.cc:199
void Restart()
Definition: metrics.h:75
void EdgeWanted(const Edge *edge)
Definition: build.cc:375
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:160
Global state (file status) for a single run.
Definition: state.h:84
Prints lines of text, possibly overprinting previously printed lines if the terminal supports it...
Definition: line_printer.h:23
We want to build the edge, have scheduled it, and are waiting for it to complete. ...
Definition: build.h:108
bool CleanNode(DependencyScan *scan, Node *node, std::string *err)
Clean the given node during the build.
Definition: build.cc:478
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual ~CommandRunner()
Definition: build.h:140
RunningEdgeMap running_edges_
Definition: build.h:275
BuildStatus * status_
Definition: build.h:224
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:56
bool success() const
Definition: build.h:150
DepfileParserOptions depfile_parser_options
Definition: build.h:176
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:800
LinePrinter printer_
Prints progress output.
Definition: build.h:278
A simple stopwatch which returns the time in seconds since Restart() was called.
Definition: metrics.h:66
bool dry_run
Definition: build.h:170
DependencyScan scan_
Definition: build.h:232
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:130
void UnmarkDependents(const Node *node, std::set< Node *> *dependents)
Definition: build.cc:637
bool FinishCommand(CommandRunner::Result *result, std::string *err)
Update status ninja logs following a command termination.
Definition: build.cc:935
void BuildEdgeStarted(const Edge *edge)
Definition: build.cc:98
virtual bool StartCommand(Edge *edge)=0