Ninja
|
00001 // Copyright 2011 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #ifndef NINJA_BUILD_H_ 00016 #define NINJA_BUILD_H_ 00017 00018 #include <cstdio> 00019 #include <map> 00020 #include <memory> 00021 #include <queue> 00022 #include <set> 00023 #include <string> 00024 #include <vector> 00025 00026 #include "graph.h" // XXX needed for DependencyScan; should rearrange. 00027 #include "exit_status.h" 00028 #include "line_printer.h" 00029 #include "metrics.h" 00030 #include "util.h" // int64_t 00031 00032 struct BuildLog; 00033 struct BuildStatus; 00034 struct DiskInterface; 00035 struct Edge; 00036 struct Node; 00037 struct State; 00038 00039 /// Plan stores the state of a build plan: what we intend to build, 00040 /// which steps we're ready to execute. 00041 struct Plan { 00042 Plan(); 00043 00044 /// Add a target to our plan (including all its dependencies). 00045 /// Returns false if we don't need to build this target; may 00046 /// fill in |err| with an error message if there's a problem. 00047 bool AddTarget(Node* node, string* err); 00048 00049 // Pop a ready edge off the queue of edges to build. 00050 // Returns NULL if there's no work to do. 00051 Edge* FindWork(); 00052 00053 /// Returns true if there's more work to be done. 00054 bool more_to_do() const { return wanted_edges_; } 00055 00056 /// Dumps the current state of the plan. 00057 void Dump(); 00058 00059 /// Mark an edge as done building. Used internally and by 00060 /// tests. 00061 void EdgeFinished(Edge* edge); 00062 00063 /// Clean the given node during the build. 00064 void CleanNode(DependencyScan* scan, Node* node); 00065 00066 /// Number of edges with commands to run. 00067 int command_edge_count() const { return command_edges_; } 00068 00069 private: 00070 bool AddSubTarget(Node* node, vector<Node*>* stack, string* err); 00071 bool CheckDependencyCycle(Node* node, vector<Node*>* stack, string* err); 00072 void NodeFinished(Node* node); 00073 00074 /// Submits a ready edge as a candidate for execution. 00075 /// The edge may be delayed from running, for example if it's a member of a 00076 /// currently-full pool. 00077 void ScheduleWork(Edge* edge); 00078 00079 /// Allows jobs blocking on |edge| to potentially resume. 00080 /// For example, if |edge| is a member of a pool, calling this may schedule 00081 /// previously pending jobs in that pool. 00082 void ResumeDelayedJobs(Edge* edge); 00083 00084 /// Keep track of which edges we want to build in this plan. If this map does 00085 /// not contain an entry for an edge, we do not want to build the entry or its 00086 /// dependents. If an entry maps to false, we do not want to build it, but we 00087 /// might want to build one of its dependents. If the entry maps to true, we 00088 /// want to build it. 00089 map<Edge*, bool> want_; 00090 00091 set<Edge*> ready_; 00092 00093 /// Total number of edges that have commands (not phony). 00094 int command_edges_; 00095 00096 /// Total remaining number of wanted edges. 00097 int wanted_edges_; 00098 }; 00099 00100 /// CommandRunner is an interface that wraps running the build 00101 /// subcommands. This allows tests to abstract out running commands. 00102 /// RealCommandRunner is an implementation that actually runs commands. 00103 struct CommandRunner { 00104 virtual ~CommandRunner() {} 00105 virtual bool CanRunMore() = 0; 00106 virtual bool StartCommand(Edge* edge) = 0; 00107 00108 /// The result of waiting for a command. 00109 struct Result { 00110 Result() : edge(NULL) {} 00111 Edge* edge; 00112 ExitStatus status; 00113 string output; 00114 bool success() const { return status == ExitSuccess; } 00115 }; 00116 /// Wait for a command to complete, or return false if interrupted. 00117 virtual bool WaitForCommand(Result* result) = 0; 00118 00119 virtual vector<Edge*> GetActiveEdges() { return vector<Edge*>(); } 00120 virtual void Abort() {} 00121 }; 00122 00123 /// Options (e.g. verbosity, parallelism) passed to a build. 00124 struct BuildConfig { 00125 BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1), 00126 failures_allowed(1), max_load_average(-0.0f) {} 00127 00128 enum Verbosity { 00129 NORMAL, 00130 QUIET, // No output -- used when testing. 00131 VERBOSE 00132 }; 00133 Verbosity verbosity; 00134 bool dry_run; 00135 int parallelism; 00136 int failures_allowed; 00137 /// The maximum load average we must not exceed. A negative value 00138 /// means that we do not have any limit. 00139 double max_load_average; 00140 }; 00141 00142 /// Builder wraps the build process: starting commands, updating status. 00143 struct Builder { 00144 Builder(State* state, const BuildConfig& config, 00145 BuildLog* build_log, DepsLog* deps_log, 00146 DiskInterface* disk_interface); 00147 ~Builder(); 00148 00149 /// Clean up after interrupted commands by deleting output files. 00150 void Cleanup(); 00151 00152 Node* AddTarget(const string& name, string* err); 00153 00154 /// Add a target to the build, scanning dependencies. 00155 /// @return false on error. 00156 bool AddTarget(Node* target, string* err); 00157 00158 /// Returns true if the build targets are already up to date. 00159 bool AlreadyUpToDate() const; 00160 00161 /// Run the build. Returns false on error. 00162 /// It is an error to call this function when AlreadyUpToDate() is true. 00163 bool Build(string* err); 00164 00165 bool StartEdge(Edge* edge, string* err); 00166 void FinishCommand(CommandRunner::Result* result); 00167 00168 /// Used for tests. 00169 void SetBuildLog(BuildLog* log) { 00170 scan_.set_build_log(log); 00171 } 00172 00173 State* state_; 00174 const BuildConfig& config_; 00175 Plan plan_; 00176 auto_ptr<CommandRunner> command_runner_; 00177 BuildStatus* status_; 00178 00179 private: 00180 bool ExtractDeps(CommandRunner::Result* result, const string& deps_type, 00181 vector<Node*>* deps_nodes, string* err); 00182 00183 DiskInterface* disk_interface_; 00184 DependencyScan scan_; 00185 00186 // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr. 00187 Builder(const Builder &other); // DO NOT IMPLEMENT 00188 void operator=(const Builder &other); // DO NOT IMPLEMENT 00189 }; 00190 00191 /// Tracks the status of a build: completion fraction, printing updates. 00192 struct BuildStatus { 00193 explicit BuildStatus(const BuildConfig& config); 00194 void PlanHasTotalEdges(int total); 00195 void BuildEdgeStarted(Edge* edge); 00196 void BuildEdgeFinished(Edge* edge, bool success, const string& output, 00197 int* start_time, int* end_time); 00198 void BuildFinished(); 00199 00200 /// Format the progress status string by replacing the placeholders. 00201 /// See the user manual for more information about the available 00202 /// placeholders. 00203 /// @param progress_status_format The format of the progress status. 00204 string FormatProgressStatus(const char* progress_status_format) const; 00205 00206 private: 00207 void PrintStatus(Edge* edge); 00208 00209 const BuildConfig& config_; 00210 00211 /// Time the build started. 00212 int64_t start_time_millis_; 00213 00214 int started_edges_, finished_edges_, total_edges_; 00215 00216 /// Map of running edge to time the edge started running. 00217 typedef map<Edge*, int> RunningEdgeMap; 00218 RunningEdgeMap running_edges_; 00219 00220 /// Prints progress output. 00221 LinePrinter printer_; 00222 00223 /// The custom progress status format to use. 00224 const char* progress_status_format_; 00225 00226 template<size_t S> 00227 void snprinfRate(double rate, char(&buf)[S], const char* format) const { 00228 if (rate == -1) snprintf(buf, S, "?"); 00229 else snprintf(buf, S, format, rate); 00230 } 00231 00232 struct RateInfo { 00233 RateInfo() : rate_(-1) {} 00234 00235 void Restart() { stopwatch_.Restart(); } 00236 double Elapsed() const { return stopwatch_.Elapsed(); } 00237 double rate() { return rate_; } 00238 00239 void UpdateRate(int edges) { 00240 if (edges && stopwatch_.Elapsed()) 00241 rate_ = edges / stopwatch_.Elapsed(); 00242 } 00243 00244 private: 00245 double rate_; 00246 Stopwatch stopwatch_; 00247 }; 00248 00249 struct SlidingRateInfo { 00250 SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {} 00251 00252 void Restart() { stopwatch_.Restart(); } 00253 double rate() { return rate_; } 00254 00255 void UpdateRate(int update_hint) { 00256 if (update_hint == last_update_) 00257 return; 00258 last_update_ = update_hint; 00259 00260 if (times_.size() == N) 00261 times_.pop(); 00262 times_.push(stopwatch_.Elapsed()); 00263 if (times_.back() != times_.front()) 00264 rate_ = times_.size() / (times_.back() - times_.front()); 00265 } 00266 00267 private: 00268 double rate_; 00269 Stopwatch stopwatch_; 00270 const size_t N; 00271 queue<double> times_; 00272 int last_update_; 00273 }; 00274 00275 mutable RateInfo overall_rate_; 00276 mutable SlidingRateInfo current_rate_; 00277 }; 00278 00279 #endif // NINJA_BUILD_H_