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_; }
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  void FinishCommand(CommandRunner::Result* result);
167 
168  /// Used for tests.
169  void SetBuildLog(BuildLog* log) {
170  scan_.set_build_log(log);
171  }
172 
176  auto_ptr<CommandRunner> command_runner_;
178 
179  private:
180  bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
181  vector<Node*>* deps_nodes, string* err);
182 
185 
186  // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
187  Builder(const Builder &other); // DO NOT IMPLEMENT
188  void operator=(const Builder &other); // DO NOT IMPLEMENT
189 };
190 
191 /// Tracks the status of a build: completion fraction, printing updates.
192 struct BuildStatus {
193  explicit BuildStatus(const BuildConfig& config);
194  void PlanHasTotalEdges(int total);
195  void BuildEdgeStarted(Edge* edge);
196  void BuildEdgeFinished(Edge* edge, bool success, const string& output,
197  int* start_time, int* end_time);
198  void BuildFinished();
199 
200  /// Format the progress status string by replacing the placeholders.
201  /// See the user manual for more information about the available
202  /// placeholders.
203  /// @param progress_status_format The format of the progress status.
204  string FormatProgressStatus(const char* progress_status_format) const;
205 
206  private:
207  void PrintStatus(Edge* edge);
208 
210 
211  /// Time the build started.
213 
215 
216  /// Map of running edge to time the edge started running.
217  typedef map<Edge*, int> RunningEdgeMap;
219 
220  /// Prints progress output.
222 
223  /// The custom progress status format to use.
225 
226  template<size_t S>
227  void snprinfRate(double rate, char(&buf)[S], const char* format) const {
228  if (rate == -1) snprintf(buf, S, "?");
229  else snprintf(buf, S, format, rate);
230  }
231 
232  struct RateInfo {
233  RateInfo() : rate_(-1) {}
234 
235  void Restart() { stopwatch_.Restart(); }
236  double Elapsed() const { return stopwatch_.Elapsed(); }
237  double rate() { return rate_; }
238 
239  void UpdateRate(int edges) {
240  if (edges && stopwatch_.Elapsed())
241  rate_ = edges / stopwatch_.Elapsed();
242  }
243 
244  private:
245  double rate_;
247  };
248 
250  SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
251 
252  void Restart() { stopwatch_.Restart(); }
253  double rate() { return rate_; }
254 
255  void UpdateRate(int update_hint) {
256  if (update_hint == last_update_)
257  return;
258  last_update_ = update_hint;
259 
260  if (times_.size() == N)
261  times_.pop();
262  times_.push(stopwatch_.Elapsed());
263  if (times_.back() != times_.front())
264  rate_ = times_.size() / (times_.back() - times_.front());
265  }
266 
267  private:
268  double rate_;
270  const size_t N;
271  queue<double> times_;
273  };
274 
277 };
278 
279 #endif // NINJA_BUILD_H_
Stopwatch stopwatch_
Definition: build.h:246
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:101
BuildStatus(const BuildConfig &config)
Definition: build.cc:73
double Elapsed() const
Definition: build.h:236
RateInfo overall_rate_
Definition: build.h:275
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:276
Plan()
Definition: build.cc:253
void UpdateRate(int edges)
Definition: build.h:239
set< Edge * > ready_
Definition: build.h:91
bool AddSubTarget(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:260
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:255
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:331
void ResumeDelayedJobs(Edge *edge)
Allows jobs blocking on |edge| to potentially resume.
Definition: build.cc:357
void ScheduleWork(Edge *edge)
Submits a ready edge as a candidate for execution.
Definition: build.cc:340
State * state_
Definition: build.h:173
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:174
int finished_edges_
Definition: build.h:214
double Elapsed() const
Seconds since Restart() call.
Definition: metrics.h:72
const BuildConfig & config_
Definition: build.h:209
void CleanNode(DependencyScan *scan, Node *node)
Clean the given node during the build.
Definition: build.cc:401
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:137
void UpdateRate(int update_hint)
Definition: build.h:255
virtual void Abort()
Definition: build.h:120
Store a log of every command ran for every build.
Definition: build_log.h:35
int started_edges_
Definition: build.h:214
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:589
void BuildEdgeStarted(Edge *edge)
Definition: build.cc:93
DiskInterface * disk_interface_
Definition: build.h:183
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:362
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:63
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:523
~Builder()
Definition: build.cc:531
map< Edge *, bool > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:89
int64_t start_time_millis_
Time the build started.
Definition: build.h:212
ExitStatus
Definition: exit_status.h:18
int total_edges_
Definition: build.h:214
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:97
void FinishCommand(CommandRunner::Result *result)
Definition: build.cc:707
ExitStatus status
Definition: build.h:112
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:535
void set_build_log(BuildLog *log)
Definition: graph.h:252
virtual bool CanRunMore()=0
auto_ptr< CommandRunner > command_runner_
Definition: build.h:176
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:169
Builder wraps the build process: starting commands, updating status.
Definition: build.h:143
void PlanHasTotalEdges(int total)
Definition: build.cc:89
void NodeFinished(Node *node)
Definition: build.cc:380
bool CheckDependencyCycle(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:311
map< Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:217
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:192
bool ExtractDeps(CommandRunner::Result *result, const string &deps_type, vector< Node * > *deps_nodes, string *err)
Definition: build.cc:799
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:224
virtual vector< Edge * > GetActiveEdges()
Definition: build.h:119
Plan plan_
Definition: build.h:175
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:230
void PrintStatus(Edge *edge)
Definition: build.cc:233
void BuildFinished()
Definition: build.cc:146
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:23
bool StartEdge(Edge *edge, string *err)
Definition: build.cc:674
void Dump()
Dumps the current state of the plan.
Definition: build.cc:452
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:218
bool Build(string *err)
Run the build.
Definition: build.cc:593
BuildStatus * status_
Definition: build.h:177
string FormatProgressStatus(const char *progress_status_format) const
Format the progress status string by replacing the placeholders.
Definition: build.cc:150
queue< double > times_
Definition: build.h:271
LinePrinter printer_
Prints progress output.
Definition: build.h:221
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:563
bool dry_run
Definition: build.h:134
DependencyScan scan_
Definition: build.h:184
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:227
virtual bool StartCommand(Edge *edge)=0