1 // Copyright 2011 Google Inc. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #ifndef NINJA_BUILD_H_
16 #define NINJA_BUILD_H_
26 #include "graph.h" // XXX needed for DependencyScan; should rearrange.
27 #include "exit_status.h"
28 #include "line_printer.h"
30 #include "util.h" // int64_t
39 /// Plan stores the state of a build plan: what we intend to build,
40 /// which steps we're ready to execute.
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);
49 // Pop a ready edge off the queue of edges to build.
50 // Returns NULL if there's no work to do.
53 /// Returns true if there's more work to be done.
54 bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
56 /// Dumps the current state of the plan.
64 /// Mark an edge as done building (whether it succeeded or failed).
65 void EdgeFinished(Edge* edge, EdgeResult result);
67 /// Clean the given node during the build.
68 /// Return false on error.
69 bool CleanNode(DependencyScan* scan, Node* node, string* err);
71 /// Number of edges with commands to run.
72 int command_edge_count() const { return command_edges_; }
75 bool AddSubTarget(Node* node, vector<Node*>* stack, string* err);
76 bool CheckDependencyCycle(Node* node, const vector<Node*>& stack,
78 void NodeFinished(Node* node);
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);
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
90 map<Edge*, bool> want_;
94 /// Total number of edges that have commands (not phony).
97 /// Total remaining number of wanted edges.
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;
109 /// The result of waiting for a command.
111 Result() : edge(NULL) {}
115 bool success() const { return status == ExitSuccess; }
117 /// Wait for a command to complete, or return false if interrupted.
118 virtual bool WaitForCommand(Result* result) = 0;
120 virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
121 virtual void Abort() {}
124 /// Options (e.g. verbosity, parallelism) passed to a build.
126 BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
127 failures_allowed(1), max_load_average(-0.0f) {}
131 QUIET, // No output -- used when testing.
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;
143 /// Builder wraps the build process: starting commands, updating status.
145 Builder(State* state, const BuildConfig& config,
146 BuildLog* build_log, DepsLog* deps_log,
147 DiskInterface* disk_interface);
150 /// Clean up after interrupted commands by deleting output files.
153 Node* AddTarget(const string& name, string* err);
155 /// Add a target to the build, scanning dependencies.
156 /// @return false on error.
157 bool AddTarget(Node* target, string* err);
159 /// Returns true if the build targets are already up to date.
160 bool AlreadyUpToDate() const;
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);
166 bool StartEdge(Edge* edge, string* err);
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);
173 void SetBuildLog(BuildLog* log) {
174 scan_.set_build_log(log);
178 const BuildConfig& config_;
180 auto_ptr<CommandRunner> command_runner_;
181 BuildStatus* status_;
184 bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
185 const string& deps_prefix, vector<Node*>* deps_nodes,
188 DiskInterface* disk_interface_;
189 DependencyScan scan_;
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
196 /// Tracks the status of a build: completion fraction, printing updates.
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();
205 /// Format the progress status string by replacing the placeholders.
206 /// See the user manual for more information about the available
208 /// @param progress_status_format The format of the progress status.
209 string FormatProgressStatus(const char* progress_status_format) const;
212 void PrintStatus(Edge* edge);
214 const BuildConfig& config_;
216 /// Time the build started.
217 int64_t start_time_millis_;
219 int started_edges_, finished_edges_, total_edges_;
221 /// Map of running edge to time the edge started running.
222 typedef map<Edge*, int> RunningEdgeMap;
223 RunningEdgeMap running_edges_;
225 /// Prints progress output.
226 LinePrinter printer_;
228 /// The custom progress status format to use.
229 const char* progress_status_format_;
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);
238 RateInfo() : rate_(-1) {}
240 void Restart() { stopwatch_.Restart(); }
241 double Elapsed() const { return stopwatch_.Elapsed(); }
242 double rate() { return rate_; }
244 void UpdateRate(int edges) {
245 if (edges && stopwatch_.Elapsed())
246 rate_ = edges / stopwatch_.Elapsed();
251 Stopwatch stopwatch_;
254 struct SlidingRateInfo {
255 SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
257 void Restart() { stopwatch_.Restart(); }
258 double rate() { return rate_; }
260 void UpdateRate(int update_hint) {
261 if (update_hint == last_update_)
263 last_update_ = update_hint;
265 if (times_.size() == N)
267 times_.push(stopwatch_.Elapsed());
268 if (times_.back() != times_.front())
269 rate_ = times_.size() / (times_.back() - times_.front());
274 Stopwatch stopwatch_;
276 queue<double> times_;
280 mutable RateInfo overall_rate_;
281 mutable SlidingRateInfo current_rate_;
284 #endif // NINJA_BUILD_H_