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 DiskInterface;
36 struct Edge;
37 struct Node;
38 struct State;
39 
40 /// Plan stores the state of a build plan: what we intend to build,
41 /// which steps we're ready to execute.
42 struct Plan {
43  Plan();
44 
45  /// Add a target to our plan (including all its dependencies).
46  /// Returns false if we don't need to build this target; may
47  /// fill in |err| with an error message if there's a problem.
48  bool AddTarget(Node* node, string* err);
49 
50  // Pop a ready edge off the queue of edges to build.
51  // Returns NULL if there's no work to do.
52  Edge* FindWork();
53 
54  /// Returns true if there's more work to be done.
55  bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
56 
57  /// Dumps the current state of the plan.
58  void Dump();
59 
60  enum EdgeResult {
63  };
64 
65  /// Mark an edge as done building (whether it succeeded or failed).
66  void EdgeFinished(Edge* edge, EdgeResult result);
67 
68  /// Clean the given node during the build.
69  /// Return false on error.
70  bool CleanNode(DependencyScan* scan, Node* node, string* err);
71 
72  /// Number of edges with commands to run.
73  int command_edge_count() const { return command_edges_; }
74 
75  /// Reset state. Clears want and ready sets.
76  void Reset();
77 
78 private:
79  bool AddSubTarget(Node* node, Node* dependent, string* err);
80  void NodeFinished(Node* node);
81 
82  /// Enumerate possible steps we want for an edge.
83  enum Want
84  {
85  /// We do not want to build the edge, but we might want to build one of
86  /// its dependents.
88  /// We want to build the edge, but have not yet scheduled it.
90  /// We want to build the edge, have scheduled it, and are waiting
91  /// for it to complete.
93  };
94 
95  /// Submits a ready edge as a candidate for execution.
96  /// The edge may be delayed from running, for example if it's a member of a
97  /// currently-full pool.
98  void ScheduleWork(map<Edge*, Want>::iterator want_e);
99 
100  /// Keep track of which edges we want to build in this plan. If this map does
101  /// not contain an entry for an edge, we do not want to build the entry or its
102  /// dependents. If it does contain an entry, the enumeration indicates what
103  /// we want for the edge.
104  map<Edge*, Want> want_;
105 
106  set<Edge*> ready_;
107 
108  /// Total number of edges that have commands (not phony).
110 
111  /// Total remaining number of wanted edges.
113 };
114 
115 /// CommandRunner is an interface that wraps running the build
116 /// subcommands. This allows tests to abstract out running commands.
117 /// RealCommandRunner is an implementation that actually runs commands.
119  virtual ~CommandRunner() {}
120  virtual bool CanRunMore() = 0;
121  virtual bool StartCommand(Edge* edge) = 0;
122 
123  /// The result of waiting for a command.
124  struct Result {
125  Result() : edge(NULL) {}
128  string output;
129  bool success() const { return status == ExitSuccess; }
130  };
131  /// Wait for a command to complete, or return false if interrupted.
132  virtual bool WaitForCommand(Result* result) = 0;
133 
134  virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
135  virtual void Abort() {}
136 };
137 
138 /// Options (e.g. verbosity, parallelism) passed to a build.
139 struct BuildConfig {
141  failures_allowed(1), max_load_average(-0.0f) {}
142 
143  enum Verbosity {
145  QUIET, // No output -- used when testing.
147  };
149  bool dry_run;
152  /// The maximum load average we must not exceed. A negative value
153  /// means that we do not have any limit.
156 };
157 
158 /// Builder wraps the build process: starting commands, updating status.
159 struct Builder {
160  Builder(State* state, const BuildConfig& config,
161  BuildLog* build_log, DepsLog* deps_log,
162  DiskInterface* disk_interface);
163  ~Builder();
164 
165  /// Clean up after interrupted commands by deleting output files.
166  void Cleanup();
167 
168  Node* AddTarget(const string& name, string* err);
169 
170  /// Add a target to the build, scanning dependencies.
171  /// @return false on error.
172  bool AddTarget(Node* target, string* err);
173 
174  /// Returns true if the build targets are already up to date.
175  bool AlreadyUpToDate() const;
176 
177  /// Run the build. Returns false on error.
178  /// It is an error to call this function when AlreadyUpToDate() is true.
179  bool Build(string* err);
180 
181  bool StartEdge(Edge* edge, string* err);
182 
183  /// Update status ninja logs following a command termination.
184  /// @return false if the build can not proceed further due to a fatal error.
185  bool FinishCommand(CommandRunner::Result* result, string* err);
186 
187  /// Used for tests.
188  void SetBuildLog(BuildLog* log) {
189  scan_.set_build_log(log);
190  }
191 
195 #if __cplusplus < 201703L
196  auto_ptr<CommandRunner> command_runner_;
197 #else
198  unique_ptr<CommandRunner> command_runner_; // auto_ptr was removed in C++17.
199 #endif
201 
202  private:
203  bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
204  const string& deps_prefix, vector<Node*>* deps_nodes,
205  string* err);
206 
209 
210  // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
211  Builder(const Builder &other); // DO NOT IMPLEMENT
212  void operator=(const Builder &other); // DO NOT IMPLEMENT
213 };
214 
215 /// Tracks the status of a build: completion fraction, printing updates.
216 struct BuildStatus {
217  explicit BuildStatus(const BuildConfig& config);
218  void PlanHasTotalEdges(int total);
219  void BuildEdgeStarted(Edge* edge);
220  void BuildEdgeFinished(Edge* edge, bool success, const string& output,
221  int* start_time, int* end_time);
222  void BuildStarted();
223  void BuildFinished();
224 
225  enum EdgeStatus {
228  };
229 
230  /// Format the progress status string by replacing the placeholders.
231  /// See the user manual for more information about the available
232  /// placeholders.
233  /// @param progress_status_format The format of the progress status.
234  /// @param status The status of the edge.
235  string FormatProgressStatus(const char* progress_status_format,
236  EdgeStatus status) const;
237 
238  private:
239  void PrintStatus(Edge* edge, EdgeStatus status);
240 
242 
243  /// Time the build started.
245 
247 
248  /// Map of running edge to time the edge started running.
249  typedef map<Edge*, int> RunningEdgeMap;
251 
252  /// Prints progress output.
254 
255  /// The custom progress status format to use.
257 
258  template<size_t S>
259  void SnprintfRate(double rate, char(&buf)[S], const char* format) const {
260  if (rate == -1)
261  snprintf(buf, S, "?");
262  else
263  snprintf(buf, S, format, rate);
264  }
265 
266  struct RateInfo {
267  RateInfo() : rate_(-1) {}
268 
269  void Restart() { stopwatch_.Restart(); }
270  double Elapsed() const { return stopwatch_.Elapsed(); }
271  double rate() { return rate_; }
272 
273  void UpdateRate(int edges) {
274  if (edges && stopwatch_.Elapsed())
275  rate_ = edges / stopwatch_.Elapsed();
276  }
277 
278  private:
279  double rate_;
281  };
282 
284  SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
285 
286  void Restart() { stopwatch_.Restart(); }
287  double rate() { return rate_; }
288 
289  void UpdateRate(int update_hint) {
290  if (update_hint == last_update_)
291  return;
292  last_update_ = update_hint;
293 
294  if (times_.size() == N)
295  times_.pop();
296  times_.push(stopwatch_.Elapsed());
297  if (times_.back() != times_.front())
298  rate_ = times_.size() / (times_.back() - times_.front());
299  }
300 
301  private:
302  double rate_;
304  const size_t N;
305  queue<double> times_;
307  };
308 
311 };
312 
313 #endif // NINJA_BUILD_H_
Stopwatch stopwatch_
Definition: build.h:280
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:118
Verbosity verbosity
Definition: build.h:148
void BuildEdgeFinished(Edge *edge, bool success, const string &output, int *start_time, int *end_time)
Definition: build.cc:111
We do not want to build the edge, but we might want to build one of its dependents.
Definition: build.h:87
BuildStatus(const BuildConfig &config)
Definition: build.cc:79
RateInfo overall_rate_
Definition: build.h:309
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:154
Plan stores the state of a build plan: what we intend to build, which steps we&#39;re ready to execute...
Definition: build.h:42
BuildConfig()
Definition: build.h:140
SlidingRateInfo current_rate_
Definition: build.h:310
Plan()
Definition: build.cc:290
void UpdateRate(int edges)
Definition: build.h:273
bool ExtractDeps(CommandRunner::Result *result, const string &deps_type, const string &deps_prefix, vector< Node *> *deps_nodes, string *err)
Definition: build.cc:869
set< Edge * > ready_
Definition: build.h:106
The result of waiting for a command.
Definition: build.h:124
string FormatProgressStatus(const char *progress_status_format, EdgeStatus status) const
Format the progress status string by replacing the placeholders.
Definition: build.cc:186
bool AddTarget(Node *node, string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:299
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:348
double Elapsed() const
Definition: build.h:270
void ScheduleWork(map< Edge *, Want >::iterator want_e)
Submits a ready edge as a candidate for execution.
Definition: build.cc:357
bool AddSubTarget(Node *node, Node *dependent, string *err)
Definition: build.cc:303
State * state_
Definition: build.h:192
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:193
int finished_edges_
Definition: build.h:246
void PrintStatus(Edge *edge, EdgeStatus status)
Definition: build.cc:274
const BuildConfig & config_
Definition: build.h:241
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:73
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:131
void UpdateRate(int update_hint)
Definition: build.h:289
virtual void Abort()
Definition: build.h:135
Store a log of every command ran for every build.
Definition: build_log.h:42
int started_edges_
Definition: build.h:246
void BuildEdgeStarted(Edge *edge)
Definition: build.cc:99
DiskInterface * disk_interface_
Definition: build.h:207
Want
Enumerate possible steps we want for an edge.
Definition: build.h:83
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:150
int failures_allowed
Definition: build.h:151
Builder(State *state, const BuildConfig &config, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface)
Definition: build.cc:556
~Builder()
Definition: build.cc:565
void BuildStarted()
Definition: build.cc:176
void Reset()
Reset state. Clears want and ready sets.
Definition: build.cc:292
bool FinishCommand(CommandRunner::Result *result, string *err)
Update status ninja logs following a command termination.
Definition: build.cc:752
int64_t start_time_millis_
Time the build started.
Definition: build.h:244
ExitStatus
Definition: exit_status.h:18
int total_edges_
Definition: build.h:246
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:112
ExitStatus status
Definition: build.h:127
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:569
void set_build_log(BuildLog *log)
Definition: graph.h:277
virtual bool CanRunMore()=0
We want to build the edge, but have not yet scheduled it.
Definition: build.h:89
map< Edge *, Want > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:104
auto_ptr< CommandRunner > command_runner_
Definition: build.h:196
double Elapsed() const
Seconds since Restart() call.
Definition: metrics.h:72
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:188
Builder wraps the build process: starting commands, updating status.
Definition: build.h:159
void PlanHasTotalEdges(int total)
Definition: build.cc:95
void NodeFinished(Node *node)
Definition: build.cc:405
EdgeResult
Definition: build.h:60
map< Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:249
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:216
void SnprintfRate(double rate, char(&buf)[S], const char *format) const
Definition: build.h:259
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:256
virtual vector< Edge * > GetActiveEdges()
Definition: build.h:134
Plan plan_
Definition: build.h:194
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:254
void BuildFinished()
Definition: build.cc:181
void Restart()
Definition: metrics.h:76
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:139
Global state (file status) for a single run.
Definition: state.h:85
Prints lines of text, possibly overprinting previously printed lines if the terminal supports it...
Definition: line_printer.h:24
bool StartEdge(Edge *edge, string *err)
Definition: build.cc:719
We want to build the edge, have scheduled it, and are waiting for it to complete. ...
Definition: build.h:92
void Dump()
Dumps the current state of the plan.
Definition: build.cc:483
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual ~CommandRunner()
Definition: build.h:119
RunningEdgeMap running_edges_
Definition: build.h:250
bool Build(string *err)
Run the build.
Definition: build.cc:629
BuildStatus * status_
Definition: build.h:200
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:55
bool CleanNode(DependencyScan *scan, Node *node, string *err)
Clean the given node during the build.
Definition: build.cc:426
bool success() const
Definition: build.h:129
void EdgeFinished(Edge *edge, EdgeResult result)
Mark an edge as done building (whether it succeeded or failed).
Definition: build.cc:379
queue< double > times_
Definition: build.h:305
DepfileParserOptions depfile_parser_options
Definition: build.h:155
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:625
LinePrinter printer_
Prints progress output.
Definition: build.h:253
A simple stopwatch which returns the time in seconds since Restart() was called.
Definition: metrics.h:67
Node * AddTarget(const string &name, string *err)
Definition: build.cc:599
bool dry_run
Definition: build.h:149
DependencyScan scan_
Definition: build.h:208
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:109
virtual bool StartCommand(Edge *edge)=0