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  /// Return false on error.
65  bool CleanNode(DependencyScan* scan, Node* node, string* err);
66 
67  /// Number of edges with commands to run.
68  int command_edge_count() const { return command_edges_; }
69 
70 private:
71  bool AddSubTarget(Node* node, vector<Node*>* stack, string* err);
72  bool CheckDependencyCycle(Node* node, const vector<Node*>& stack,
73  string* err);
74  void NodeFinished(Node* node);
75 
76  /// Submits a ready edge as a candidate for execution.
77  /// The edge may be delayed from running, for example if it's a member of a
78  /// currently-full pool.
79  void ScheduleWork(Edge* edge);
80 
81  /// Keep track of which edges we want to build in this plan. If this map does
82  /// not contain an entry for an edge, we do not want to build the entry or its
83  /// dependents. If an entry maps to false, we do not want to build it, but we
84  /// might want to build one of its dependents. If the entry maps to true, we
85  /// want to build it.
86  map<Edge*, bool> want_;
87 
88  set<Edge*> ready_;
89 
90  /// Total number of edges that have commands (not phony).
92 
93  /// Total remaining number of wanted edges.
95 };
96 
97 /// CommandRunner is an interface that wraps running the build
98 /// subcommands. This allows tests to abstract out running commands.
99 /// RealCommandRunner is an implementation that actually runs commands.
101  virtual ~CommandRunner() {}
102  virtual bool CanRunMore() = 0;
103  virtual bool StartCommand(Edge* edge) = 0;
104 
105  /// The result of waiting for a command.
106  struct Result {
107  Result() : edge(NULL) {}
110  string output;
111  bool success() const { return status == ExitSuccess; }
112  };
113  /// Wait for a command to complete, or return false if interrupted.
114  virtual bool WaitForCommand(Result* result) = 0;
115 
116  virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
117  virtual void Abort() {}
118 };
119 
120 /// Options (e.g. verbosity, parallelism) passed to a build.
121 struct BuildConfig {
123  failures_allowed(1), max_load_average(-0.0f) {}
124 
125  enum Verbosity {
127  QUIET, // No output -- used when testing.
129  };
131  bool dry_run;
134  /// The maximum load average we must not exceed. A negative value
135  /// means that we do not have any limit.
137 };
138 
139 /// Builder wraps the build process: starting commands, updating status.
140 struct Builder {
141  Builder(State* state, const BuildConfig& config,
142  BuildLog* build_log, DepsLog* deps_log,
143  DiskInterface* disk_interface);
144  ~Builder();
145 
146  /// Clean up after interrupted commands by deleting output files.
147  void Cleanup();
148 
149  Node* AddTarget(const string& name, string* err);
150 
151  /// Add a target to the build, scanning dependencies.
152  /// @return false on error.
153  bool AddTarget(Node* target, string* err);
154 
155  /// Returns true if the build targets are already up to date.
156  bool AlreadyUpToDate() const;
157 
158  /// Run the build. Returns false on error.
159  /// It is an error to call this function when AlreadyUpToDate() is true.
160  bool Build(string* err);
161 
162  bool StartEdge(Edge* edge, string* err);
163 
164  /// Update status ninja logs following a command termination.
165  /// @return false if the build can not proceed further due to a fatal error.
166  bool FinishCommand(CommandRunner::Result* result, string* err);
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  const string& deps_prefix, vector<Node*>* deps_nodes,
182  string* err);
183 
186 
187  // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
188  Builder(const Builder &other); // DO NOT IMPLEMENT
189  void operator=(const Builder &other); // DO NOT IMPLEMENT
190 };
191 
192 /// Tracks the status of a build: completion fraction, printing updates.
193 struct BuildStatus {
194  explicit BuildStatus(const BuildConfig& config);
195  void PlanHasTotalEdges(int total);
196  void BuildEdgeStarted(Edge* edge);
197  void BuildEdgeFinished(Edge* edge, bool success, const string& output,
198  int* start_time, int* end_time);
199  void BuildFinished();
200 
201  /// Format the progress status string by replacing the placeholders.
202  /// See the user manual for more information about the available
203  /// placeholders.
204  /// @param progress_status_format The format of the progress status.
205  string FormatProgressStatus(const char* progress_status_format) const;
206 
207  private:
208  void PrintStatus(Edge* edge);
209 
211 
212  /// Time the build started.
214 
216 
217  /// Map of running edge to time the edge started running.
218  typedef map<Edge*, int> RunningEdgeMap;
220 
221  /// Prints progress output.
223 
224  /// The custom progress status format to use.
226 
227  template<size_t S>
228  void snprinfRate(double rate, char(&buf)[S], const char* format) const {
229  if (rate == -1) snprintf(buf, S, "?");
230  else snprintf(buf, S, format, rate);
231  }
232 
233  struct RateInfo {
234  RateInfo() : rate_(-1) {}
235 
236  void Restart() { stopwatch_.Restart(); }
237  double Elapsed() const { return stopwatch_.Elapsed(); }
238  double rate() { return rate_; }
239 
240  void UpdateRate(int edges) {
241  if (edges && stopwatch_.Elapsed())
242  rate_ = edges / stopwatch_.Elapsed();
243  }
244 
245  private:
246  double rate_;
248  };
249 
251  SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
252 
253  void Restart() { stopwatch_.Restart(); }
254  double rate() { return rate_; }
255 
256  void UpdateRate(int update_hint) {
257  if (update_hint == last_update_)
258  return;
259  last_update_ = update_hint;
260 
261  if (times_.size() == N)
262  times_.pop();
263  times_.push(stopwatch_.Elapsed());
264  if (times_.back() != times_.front())
265  rate_ = times_.size() / (times_.back() - times_.front());
266  }
267 
268  private:
269  double rate_;
271  const size_t N;
272  queue<double> times_;
274  };
275 
278 };
279 
280 #endif // NINJA_BUILD_H_
Stopwatch stopwatch_
Definition: build.h:247
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:100
Verbosity verbosity
Definition: build.h:130
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:237
RateInfo overall_rate_
Definition: build.h:276
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:136
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:122
SlidingRateInfo current_rate_
Definition: build.h:277
Plan()
Definition: build.cc:261
void UpdateRate(int edges)
Definition: build.h:240
set< Edge * > ready_
Definition: build.h:88
bool AddSubTarget(Node *node, vector< Node * > *stack, string *err)
Definition: build.cc:268
The result of waiting for a command.
Definition: build.h:106
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:111
Edge * FindWork()
Definition: build.cc:351
void ScheduleWork(Edge *edge)
Submits a ready edge as a candidate for execution.
Definition: build.cc:360
State * state_
Definition: build.h:173
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:174
int finished_edges_
Definition: build.h:215
double Elapsed() const
Seconds since Restart() call.
Definition: metrics.h:72
const BuildConfig & config_
Definition: build.h:210
bool ExtractDeps(CommandRunner::Result *result, const string &deps_type, const string &deps_prefix, vector< Node * > *deps_nodes, string *err)
Definition: build.cc:844
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:124
void UpdateRate(int update_hint)
Definition: build.h:256
virtual void Abort()
Definition: build.h:117
Store a log of every command ran for every build.
Definition: build_log.h:42
int started_edges_
Definition: build.h:215
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:611
void BuildEdgeStarted(Edge *edge)
Definition: build.cc:94
DiskInterface * disk_interface_
Definition: build.h:184
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:68
void EdgeFinished(Edge *edge)
Mark an edge as done building.
Definition: build.cc:377
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:132
int failures_allowed
Definition: build.h:133
Builder(State *state, const BuildConfig &config, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface)
Definition: build.cc:544
~Builder()
Definition: build.cc:552
map< Edge *, bool > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:86
bool FinishCommand(CommandRunner::Result *result, string *err)
Update status ninja logs following a command termination.
Definition: build.cc:735
int64_t start_time_millis_
Time the build started.
Definition: build.h:213
ExitStatus
Definition: exit_status.h:18
int total_edges_
Definition: build.h:215
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:94
ExitStatus status
Definition: build.h:109
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:556
void set_build_log(BuildLog *log)
Definition: graph.h:247
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:140
void PlanHasTotalEdges(int total)
Definition: build.cc:90
void NodeFinished(Node *node)
Definition: build.cc:398
map< Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:218
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:193
const char * progress_status_format_
The custom progress status format to use.
Definition: build.h:225
virtual vector< Edge * > GetActiveEdges()
Definition: build.h:116
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:226
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:121
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:24
bool StartEdge(Edge *edge, string *err)
Definition: build.cc:702
void Dump()
Dumps the current state of the plan.
Definition: build.cc:471
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual ~CommandRunner()
Definition: build.h:101
RunningEdgeMap running_edges_
Definition: build.h:219
bool Build(string *err)
Run the build.
Definition: build.cc:615
BuildStatus * status_
Definition: build.h:177
bool CleanNode(DependencyScan *scan, Node *node, string *err)
Clean the given node during the build.
Definition: build.cc:419
bool CheckDependencyCycle(Node *node, const vector< Node * > &stack, string *err)
Definition: build.cc:319
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:272
LinePrinter printer_
Prints progress output.
Definition: build.h:222
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:586
bool dry_run
Definition: build.h:131
DependencyScan scan_
Definition: build.h:185
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:91
void snprinfRate(double rate, char(&buf)[S], const char *format) const
Definition: build.h:228
virtual bool StartCommand(Edge *edge)=0