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