3a7183f1c7765c37a83a124839b36c575e1aebd8
[platform/upstream/ninja.git] / src / build.h
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 (whether it succeeded or failed).
60   void EdgeFinished(Edge* edge, bool success);
61
62   /// Clean the given node during the build.
63   /// Return false on error.
64   bool CleanNode(DependencyScan* scan, Node* node, string* err);
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, const vector<Node*>& stack,
72                             string* err);
73   void NodeFinished(Node* node);
74
75   /// Submits a ready edge as a candidate for execution.
76   /// The edge may be delayed from running, for example if it's a member of a
77   /// currently-full pool.
78   void ScheduleWork(Edge* edge);
79
80   /// Keep track of which edges we want to build in this plan.  If this map does
81   /// not contain an entry for an edge, we do not want to build the entry or its
82   /// dependents.  If an entry maps to false, we do not want to build it, but we
83   /// might want to build one of its dependents.  If the entry maps to true, we
84   /// want to build it.
85   map<Edge*, bool> want_;
86
87   set<Edge*> ready_;
88
89   /// Total number of edges that have commands (not phony).
90   int command_edges_;
91
92   /// Total remaining number of wanted edges.
93   int wanted_edges_;
94 };
95
96 /// CommandRunner is an interface that wraps running the build
97 /// subcommands.  This allows tests to abstract out running commands.
98 /// RealCommandRunner is an implementation that actually runs commands.
99 struct CommandRunner {
100   virtual ~CommandRunner() {}
101   virtual bool CanRunMore() = 0;
102   virtual bool StartCommand(Edge* edge) = 0;
103
104   /// The result of waiting for a command.
105   struct Result {
106     Result() : edge(NULL) {}
107     Edge* edge;
108     ExitStatus status;
109     string output;
110     bool success() const { return status == ExitSuccess; }
111   };
112   /// Wait for a command to complete, or return false if interrupted.
113   virtual bool WaitForCommand(Result* result) = 0;
114
115   virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
116   virtual void Abort() {}
117 };
118
119 /// Options (e.g. verbosity, parallelism) passed to a build.
120 struct BuildConfig {
121   BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
122                   failures_allowed(1), max_load_average(-0.0f) {}
123
124   enum Verbosity {
125     NORMAL,
126     QUIET,  // No output -- used when testing.
127     VERBOSE
128   };
129   Verbosity verbosity;
130   bool dry_run;
131   int parallelism;
132   int failures_allowed;
133   /// The maximum load average we must not exceed. A negative value
134   /// means that we do not have any limit.
135   double max_load_average;
136 };
137
138 /// Builder wraps the build process: starting commands, updating status.
139 struct Builder {
140   Builder(State* state, const BuildConfig& config,
141           BuildLog* build_log, DepsLog* deps_log,
142           DiskInterface* disk_interface);
143   ~Builder();
144
145   /// Clean up after interrupted commands by deleting output files.
146   void Cleanup();
147
148   Node* AddTarget(const string& name, string* err);
149
150   /// Add a target to the build, scanning dependencies.
151   /// @return false on error.
152   bool AddTarget(Node* target, string* err);
153
154   /// Returns true if the build targets are already up to date.
155   bool AlreadyUpToDate() const;
156
157   /// Run the build.  Returns false on error.
158   /// It is an error to call this function when AlreadyUpToDate() is true.
159   bool Build(string* err);
160
161   bool StartEdge(Edge* edge, string* err);
162
163   /// Update status ninja logs following a command termination.
164   /// @return false if the build can not proceed further due to a fatal error.
165   bool FinishCommand(CommandRunner::Result* result, string* err);
166
167   /// Used for tests.
168   void SetBuildLog(BuildLog* log) {
169     scan_.set_build_log(log);
170   }
171
172   State* state_;
173   const BuildConfig& config_;
174   Plan plan_;
175   auto_ptr<CommandRunner> command_runner_;
176   BuildStatus* status_;
177
178  private:
179    bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
180                     const string& deps_prefix, vector<Node*>* deps_nodes,
181                     string* err);
182
183   DiskInterface* disk_interface_;
184   DependencyScan scan_;
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
209   const BuildConfig& config_;
210
211   /// Time the build started.
212   int64_t start_time_millis_;
213
214   int started_edges_, finished_edges_, total_edges_;
215
216   /// Map of running edge to time the edge started running.
217   typedef map<Edge*, int> RunningEdgeMap;
218   RunningEdgeMap running_edges_;
219
220   /// Prints progress output.
221   LinePrinter printer_;
222
223   /// The custom progress status format to use.
224   const char* progress_status_format_;
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_;
246     Stopwatch stopwatch_;
247   };
248
249   struct SlidingRateInfo {
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_;
269     Stopwatch stopwatch_;
270     const size_t N;
271     queue<double> times_;
272     int last_update_;
273   };
274
275   mutable RateInfo overall_rate_;
276   mutable SlidingRateInfo current_rate_;
277 };
278
279 #endif  // NINJA_BUILD_H_