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.
59 /// Mark an edge as done building (whether it succeeded or failed).
60 void EdgeFinished(Edge* edge, bool success);
62 /// Clean the given node during the build.
63 /// Return false on error.
64 bool CleanNode(DependencyScan* scan, Node* node, string* err);
66 /// Number of edges with commands to run.
67 int command_edge_count() const { return command_edges_; }
70 bool AddSubTarget(Node* node, vector<Node*>* stack, string* err);
71 bool CheckDependencyCycle(Node* node, const vector<Node*>& stack,
73 void NodeFinished(Node* node);
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);
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
85 map<Edge*, bool> want_;
89 /// Total number of edges that have commands (not phony).
92 /// Total remaining number of wanted edges.
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;
104 /// The result of waiting for a command.
106 Result() : edge(NULL) {}
110 bool success() const { return status == ExitSuccess; }
112 /// Wait for a command to complete, or return false if interrupted.
113 virtual bool WaitForCommand(Result* result) = 0;
115 virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); }
116 virtual void Abort() {}
119 /// Options (e.g. verbosity, parallelism) passed to a build.
121 BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
122 failures_allowed(1), max_load_average(-0.0f) {}
126 QUIET, // No output -- used when testing.
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;
138 /// Builder wraps the build process: starting commands, updating status.
140 Builder(State* state, const BuildConfig& config,
141 BuildLog* build_log, DepsLog* deps_log,
142 DiskInterface* disk_interface);
145 /// Clean up after interrupted commands by deleting output files.
148 Node* AddTarget(const string& name, string* err);
150 /// Add a target to the build, scanning dependencies.
151 /// @return false on error.
152 bool AddTarget(Node* target, string* err);
154 /// Returns true if the build targets are already up to date.
155 bool AlreadyUpToDate() const;
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);
161 bool StartEdge(Edge* edge, string* err);
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);
168 void SetBuildLog(BuildLog* log) {
169 scan_.set_build_log(log);
173 const BuildConfig& config_;
175 auto_ptr<CommandRunner> command_runner_;
176 BuildStatus* status_;
179 bool ExtractDeps(CommandRunner::Result* result, const string& deps_type,
180 const string& deps_prefix, vector<Node*>* deps_nodes,
183 DiskInterface* disk_interface_;
184 DependencyScan scan_;
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
191 /// Tracks the status of a build: completion fraction, printing updates.
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();
200 /// Format the progress status string by replacing the placeholders.
201 /// See the user manual for more information about the available
203 /// @param progress_status_format The format of the progress status.
204 string FormatProgressStatus(const char* progress_status_format) const;
207 void PrintStatus(Edge* edge);
209 const BuildConfig& config_;
211 /// Time the build started.
212 int64_t start_time_millis_;
214 int started_edges_, finished_edges_, total_edges_;
216 /// Map of running edge to time the edge started running.
217 typedef map<Edge*, int> RunningEdgeMap;
218 RunningEdgeMap running_edges_;
220 /// Prints progress output.
221 LinePrinter printer_;
223 /// The custom progress status format to use.
224 const char* progress_status_format_;
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);
233 RateInfo() : rate_(-1) {}
235 void Restart() { stopwatch_.Restart(); }
236 double Elapsed() const { return stopwatch_.Elapsed(); }
237 double rate() { return rate_; }
239 void UpdateRate(int edges) {
240 if (edges && stopwatch_.Elapsed())
241 rate_ = edges / stopwatch_.Elapsed();
246 Stopwatch stopwatch_;
249 struct SlidingRateInfo {
250 SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {}
252 void Restart() { stopwatch_.Restart(); }
253 double rate() { return rate_; }
255 void UpdateRate(int update_hint) {
256 if (update_hint == last_update_)
258 last_update_ = update_hint;
260 if (times_.size() == N)
262 times_.push(stopwatch_.Elapsed());
263 if (times_.back() != times_.front())
264 rate_ = times_.size() / (times_.back() - times_.front());
269 Stopwatch stopwatch_;
271 queue<double> times_;
275 mutable RateInfo overall_rate_;
276 mutable SlidingRateInfo current_rate_;
279 #endif // NINJA_BUILD_H_