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 "graph.h" // XXX needed for DependencyScan; should rearrange.
27 #include "exit_status.h"
28 #include "line_printer.h"
29 #include "metrics.h"
30 #include "util.h" // int64_t
31 
32 struct BuildLog;
33 struct BuildStatus;
34 struct DiskInterface;
35 struct Edge;
36 struct Node;
37 struct State;
38 
39 /// Plan stores the state of a build plan: what we intend to build,
40 /// which steps we're ready to execute.
41 struct Plan {
42  Plan();
43 
44  /// Add a target to our plan (including all its dependencies).
45  /// Returns false if we don't need to build this target; may
46  /// fill in |err| with an error message if there's a problem.
47  bool AddTarget(Node* node, string* err);
48 
49  // Pop a ready edge off the queue of edges to build.
50  // Returns NULL if there's no work to do.
51  Edge* FindWork();
52 
53  /// Returns true if there's more work to be done.
54  bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
55 
56  /// Dumps the current state of the plan.
57  void Dump();
58 
59  /// Mark an edge as done building. Used internally and by
60  /// tests.
61  void EdgeFinished(Edge* edge);
62 
63  /// Clean the given node during the build.
64  void CleanNode(DependencyScan* scan, Node* node);
65 
66  /// Number of edges with commands to run.
67  int command_edge_count() const { return command_edges_; }
68 
69 private:
70  bool AddSubTarget(Node* node, vector<Node*>* stack, string* err);
71  bool CheckDependencyCycle(Node* node, vector<Node*>* stack, string* err);
72  void NodeFinished(Node* node);
73 
74  /// Submits a ready edge as a candidate for execution.
75  /// The edge may be delayed from running, for example if it's a member of a
76  /// currently-full pool.
77  void ScheduleWork(Edge* edge);
78 
79  /// Allows jobs blocking on |edge| to potentially resume.
80  /// For example, if |edge| is a member of a pool, calling this may schedule
81  /// previously pending jobs in that pool.
82  void ResumeDelayedJobs(Edge* edge);
83 
84  /// Keep track of which edges we want to build in this plan. If this map does
85  /// not contain an entry for an edge, we do not want to build the entry or its
86  /// dependents. If an entry maps to false, we do not want to build it, but we
87  /// might want to build one of its dependents. If the entry maps to true, we
88  /// want to build it.
89  map<Edge*, bool> want_;
90 
91  set<Edge*> ready_;
92 
93  /// Total number of edges that have commands (not phony).
95 
96  /// Total remaining number of wanted edges.
98 };
99 
100 /// CommandRunner is an interface that wraps running the build
101 /// subcommands. This allows tests to abstract out running commands.
102 /// RealCommandRunner is an implementation that actually runs commands.
104  virtual ~CommandRunner() {}
105  virtual bool CanRunMore() = 0;
106  virtual bool StartCommand(Edge* edge) = 0;
107 
108  /// The result of waiting for a command.
109  struct Result {
110  Result() : edge(NULL) {}
113  string output;
114  bool success() const { return status == ExitSuccess; }
115  };
116  /// Wait for a command to complete, or return false if interrupted.
117  virtual bool WaitForCommand(Result* result) = 0;
118 
119  virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
120  virtual void Abort() {}
121 };
122 
123 /// Options (e.g. verbosity, parallelism) passed to a build.
124 struct BuildConfig {
126  failures_allowed(1), max_load_average(-0.0f) {}
127 
128  enum Verbosity {
130  QUIET, // No output -- used when testing.
132  };
134  bool dry_run;
137  /// The maximum load average we must not exceed. A negative value
138  /// means that we do not have any limit.
140 };
141 
142 /// Builder wraps the build process: starting commands, updating status.
143 struct Builder {
144  Builder(State* state, const BuildConfig& config,
145  BuildLog* build_log, DepsLog* deps_log,
146  DiskInterface* disk_interface);
147  ~Builder();
148 
149  /// Clean up after interrupted commands by deleting output files.
150  void Cleanup();
151 
152  Node* AddTarget(const string& name, string* err);
153 
154  /// Add a target to the build, scanning dependencies.
155  /// @return false on error.
156  bool AddTarget(Node* target, string* err);
157 
158  /// Returns true if the build targets are already up to date.
159  bool AlreadyUpToDate() const;
160 
161  /// Run the build. Returns false on error.
162  /// It is an error to call this function when AlreadyUpToDate() is true.
163  bool Build(string* err);
164 
165  bool StartEdge(Edge* edge, string* err);
166 
167  /// Update status ninja logs following a command termination.
168  /// @return false if the build can not proceed further due to a fatal error.
169  bool FinishCommand(CommandRunner::Result* result, string* err);
170 
171  /// Used for tests.
172  void SetBuildLog(BuildLog* log) {
173  scan_.set_build_log(log);
174  }
175 
179  auto_ptr<CommandRunner> command_runner_;
181 
182  private:
183  bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
184  const string& deps_prefix, vector<Node*>* deps_nodes,
185  string* err);
186 
189 
190  // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
191  Builder(const Builder &other); // DO NOT IMPLEMENT
192  void operator=(const Builder &other); // DO NOT IMPLEMENT
193 };
194 
195 /// Tracks the status of a build: completion fraction, printing updates.
196 struct BuildStatus {
197  explicit BuildStatus(const BuildConfig& config);
198  void PlanHasTotalEdges(int total);
199  void BuildEdgeStarted(Edge* edge);
200  void BuildEdgeFinished(Edge* edge, bool success, const string& output,
201  int* start_time, int* end_time);
202  void BuildFinished();
203 
204  /// Format the progress status string by replacing the placeholders.
205  /// See the user manual for more information about the available
206  /// placeholders.
207  /// @param progress_status_format The format of the progress status.
208  string FormatProgressStatus(const char* progress_status_format) const;
209 
210  private:
211  void PrintStatus(Edge* edge);
212 
214 
215  /// Time the build started.
217 
219 
220  /// Map of running edge to time the edge started running.
221  typedef map<Edge*, int> RunningEdgeMap;
223 
224  /// Prints progress output.
226 
227  /// The custom progress status format to use.
229 
230  template<size_t S>
231  void snprinfRate(double rate, char(&buf)[S], const char* format) const {
232  if (rate == -1) snprintf(buf, S, "?");
233  else snprintf(buf, S, format, rate);
234  }
235 
236  struct RateInfo {
237  RateInfo() : rate_(-1) {}
238 
239  void Restart() { stopwatch_.Restart(); }
240  double Elapsed() const { return stopwatch_.Elapsed(); }
241  double rate() { return rate_; }
242 
243  void UpdateRate(int edges) {
244  if (edges && stopwatch_.Elapsed())
245  rate_ = edges / stopwatch_.Elapsed();
246  }
247 
248  private:
249  double rate_;
251  };
252 
254  SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
255 
256  void Restart() { stopwatch_.Restart(); }
257  double rate() { return rate_; }
258 
259  void UpdateRate(int update_hint) {
260  if (update_hint == last_update_)
261  return;
262  last_update_ = update_hint;
263 
264  if (times_.size() == N)
265  times_.pop();
266  times_.push(stopwatch_.Elapsed());
267  if (times_.back() != times_.front())
268  rate_ = times_.size() / (times_.back() - times_.front());
269  }
270 
271  private:
272  double rate_;
274  const size_t N;
275  queue<double> times_;
277  };
278 
281 };
282 
283 #endif // NINJA_BUILD_H_
Stopwatch stopwatch_
Definition: build.h:250
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:103
Verbosity verbosity
Definition: build.h:133
void BuildEdgeFinished(Edge *edge, bool success, const string &output, int *start_time, int *end_time)
Definition: build.cc:105
BuildStatus(const BuildConfig &config)
Definition: build.cc:74
double Elapsed() const
Definition: build.h:240
RateInfo overall_rate_
Definition: build.h:279
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:139
Plan stores the state of a build plan: what we intend to build, which steps we're ready to execute...
Definition: build.h:41
bool more_to_do() const
Returns true if there's more work to be done.
Definition: build.h:54
BuildConfig()
Definition: build.h:125
SlidingRateInfo current_rate_
Definition: build.h:280
Plan()
Definition: build.cc:261
void UpdateRate(int edges)
Definition: build.h:243
set< Edge * > ready_
Definition: build.h:91
bool AddSubTarget(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:268
The result of waiting for a command.
Definition: build.h:109
bool AddTarget(Node *node, string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:263
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:339
void ResumeDelayedJobs(Edge *edge)
Allows jobs blocking on |edge| to potentially resume.
Definition: build.cc:365
void ScheduleWork(Edge *edge)
Submits a ready edge as a candidate for execution.
Definition: build.cc:348
State * state_
Definition: build.h:176
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:177
int finished_edges_
Definition: build.h:218
double Elapsed() const
Seconds since Restart() call.
Definition: metrics.h:72
const BuildConfig & config_
Definition: build.h:213
void CleanNode(DependencyScan *scan, Node *node)
Clean the given node during the build.
Definition: build.cc:409
bool ExtractDeps(CommandRunner::Result *result, const string &deps_type, const string &deps_prefix, vector< Node * > *deps_nodes, string *err)
Definition: build.cc:817
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:146
void UpdateRate(int update_hint)
Definition: build.h:259
virtual void Abort()
Definition: build.h:120
Store a log of every command ran for every build.
Definition: build_log.h:42
int started_edges_
Definition: build.h:218
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:593
void BuildEdgeStarted(Edge *edge)
Definition: build.cc:94
DiskInterface * disk_interface_
Definition: build.h:187
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:67
void EdgeFinished(Edge *edge)
Mark an edge as done building.
Definition: build.cc:370
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:66
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:21
void operator=(const Builder &other)
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:527
~Builder()
Definition: build.cc:535
map< Edge *, bool > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:89
bool FinishCommand(CommandRunner::Result *result, string *err)
Update status ninja logs following a command termination.
Definition: build.cc:717
int64_t start_time_millis_
Time the build started.
Definition: build.h:216
ExitStatus
Definition: exit_status.h:18
int total_edges_
Definition: build.h:218
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:97
ExitStatus status
Definition: build.h:112
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:539
void set_build_log(BuildLog *log)
Definition: graph.h:267
virtual bool CanRunMore()=0
auto_ptr< CommandRunner > command_runner_
Definition: build.h:179
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:172
Builder wraps the build process: starting commands, updating status.
Definition: build.h:143
void PlanHasTotalEdges(int total)
Definition: build.cc:90
void NodeFinished(Node *node)
Definition: build.cc:388
bool CheckDependencyCycle(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:319
map< Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:221
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:196
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:228
virtual vector< Edge * > GetActiveEdges()
Definition: build.h:119
Plan plan_
Definition: build.h:178
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:247
void PrintStatus(Edge *edge)
Definition: build.cc:241
void BuildFinished()
Definition: build.cc:153
void Restart()
Definition: metrics.h:76
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
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:684
void Dump()
Dumps the current state of the plan.
Definition: build.cc:454
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual ~CommandRunner()
Definition: build.h:104
RunningEdgeMap running_edges_
Definition: build.h:222
bool Build(string *err)
Run the build.
Definition: build.cc:597
BuildStatus * status_
Definition: build.h:180
string FormatProgressStatus(const char *progress_status_format) const
Format the progress status string by replacing the placeholders.
Definition: build.cc:158
queue< double > times_
Definition: build.h:275
LinePrinter printer_
Prints progress output.
Definition: build.h:225
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:567
bool dry_run
Definition: build.h:134
DependencyScan scan_
Definition: build.h:188
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:231
virtual bool StartCommand(Edge *edge)=0