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 <string> 22 #include <vector> 23 #include <queue> 24 25 #include "depfile_parser.h" 26 #include "graph.h" // XXX needed for DependencyScan; should rearrange. 27 #include "graph.h" 28 #include "exit_status.h" 29 #include "util.h" // int64_t 30 31 struct BuildLog; 32 struct Builder; 33 struct DiskInterface; 34 struct Edge; 35 struct Node; 36 struct State; 37 struct Status; 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(Builder* builder = NULL); 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(const Node* target, std::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. more_to_doPlan54 bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; } 55 56 /// Dumps the current state of the plan. 57 void Dump() const; 58 59 enum EdgeResult { 60 kEdgeFailed, 61 kEdgeSucceeded 62 }; 63 64 /// Mark an edge as done building (whether it succeeded or failed). 65 /// If any of the edge's outputs are dyndep bindings of their dependents, 66 /// this loads dynamic dependencies from the nodes' paths. 67 /// Returns 'false' if loading dyndep info fails and 'true' otherwise. 68 bool EdgeFinished(Edge* edge, EdgeResult result, std::string* err); 69 70 /// Clean the given node during the build. 71 /// Return false on error. 72 bool CleanNode(DependencyScan* scan, Node* node, std::string* err); 73 74 /// Number of edges with commands to run. command_edge_countPlan75 int command_edge_count() const { return command_edges_; } 76 77 /// Reset state. Clears want and ready sets. 78 void Reset(); 79 80 /// Update the build plan to account for modifications made to the graph 81 /// by information loaded from a dyndep file. 82 bool DyndepsLoaded(DependencyScan* scan, const Node* node, 83 const DyndepFile& ddf, std::string* err); 84 85 private: 86 bool RefreshDyndepDependents(DependencyScan* scan, const Node* node, std::string* err); 87 void UnmarkDependents(const Node* node, std::set<Node*>* dependents); 88 bool AddSubTarget(const Node* node, const Node* dependent, std::string* err, 89 std::set<Edge*>* dyndep_walk); 90 91 /// Update plan with knowledge that the given node is up to date. 92 /// If the node is a dyndep binding on any of its dependents, this 93 /// loads dynamic dependencies from the node's path. 94 /// Returns 'false' if loading dyndep info fails and 'true' otherwise. 95 bool NodeFinished(Node* node, std::string* err); 96 97 /// Enumerate possible steps we want for an edge. 98 enum Want 99 { 100 /// We do not want to build the edge, but we might want to build one of 101 /// its dependents. 102 kWantNothing, 103 /// We want to build the edge, but have not yet scheduled it. 104 kWantToStart, 105 /// We want to build the edge, have scheduled it, and are waiting 106 /// for it to complete. 107 kWantToFinish 108 }; 109 110 void EdgeWanted(const Edge* edge); 111 bool EdgeMaybeReady(std::map<Edge*, Want>::iterator want_e, std::string* err); 112 113 /// Submits a ready edge as a candidate for execution. 114 /// The edge may be delayed from running, for example if it's a member of a 115 /// currently-full pool. 116 void ScheduleWork(std::map<Edge*, Want>::iterator want_e); 117 118 /// Keep track of which edges we want to build in this plan. If this map does 119 /// not contain an entry for an edge, we do not want to build the entry or its 120 /// dependents. If it does contain an entry, the enumeration indicates what 121 /// we want for the edge. 122 std::map<Edge*, Want> want_; 123 124 EdgeSet ready_; 125 126 Builder* builder_; 127 128 /// Total number of edges that have commands (not phony). 129 int command_edges_; 130 131 /// Total remaining number of wanted edges. 132 int wanted_edges_; 133 }; 134 135 /// CommandRunner is an interface that wraps running the build 136 /// subcommands. This allows tests to abstract out running commands. 137 /// RealCommandRunner is an implementation that actually runs commands. 138 struct CommandRunner { ~CommandRunnerCommandRunner139 virtual ~CommandRunner() {} 140 virtual size_t CanRunMore() const = 0; 141 virtual bool StartCommand(Edge* edge) = 0; 142 143 /// The result of waiting for a command. 144 struct Result { ResultCommandRunner::Result145 Result() : edge(NULL) {} 146 Edge* edge; 147 ExitStatus status; 148 std::string output; successCommandRunner::Result149 bool success() const { return status == ExitSuccess; } 150 }; 151 /// Wait for a command to complete, or return false if interrupted. 152 virtual bool WaitForCommand(Result* result) = 0; 153 GetActiveEdgesCommandRunner154 virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); } AbortCommandRunner155 virtual void Abort() {} 156 }; 157 158 /// Options (e.g. verbosity, parallelism) passed to a build. 159 struct BuildConfig { BuildConfigBuildConfig160 BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1), 161 failures_allowed(1), max_load_average(-0.0f) {} 162 163 enum Verbosity { 164 QUIET, // No output -- used when testing. 165 NO_STATUS_UPDATE, // just regular output but suppress status update 166 NORMAL, // regular output and status update 167 VERBOSE 168 }; 169 Verbosity verbosity; 170 bool dry_run; 171 int parallelism; 172 int failures_allowed; 173 /// The maximum load average we must not exceed. A negative value 174 /// means that we do not have any limit. 175 double max_load_average; 176 DepfileParserOptions depfile_parser_options; 177 }; 178 179 /// Builder wraps the build process: starting commands, updating status. 180 struct Builder { 181 Builder(State* state, const BuildConfig& config, 182 BuildLog* build_log, DepsLog* deps_log, 183 DiskInterface* disk_interface, Status* status, 184 int64_t start_time_millis); 185 ~Builder(); 186 187 /// Clean up after interrupted commands by deleting output files. 188 void Cleanup(); 189 190 Node* AddTarget(const std::string& name, std::string* err); 191 192 /// Add a target to the build, scanning dependencies. 193 /// @return false on error. 194 bool AddTarget(Node* target, std::string* err); 195 196 /// Returns true if the build targets are already up to date. 197 bool AlreadyUpToDate() const; 198 199 /// Run the build. Returns false on error. 200 /// It is an error to call this function when AlreadyUpToDate() is true. 201 bool Build(std::string* err); 202 203 bool StartEdge(Edge* edge, std::string* err); 204 205 std::string GetContent(Edge* edge); 206 207 /// Update status ninja logs following a command termination. 208 /// @return false if the build can not proceed further due to a fatal error. 209 bool FinishCommand(CommandRunner::Result* result, std::string* err); 210 211 /// Used for tests. SetBuildLogBuilder212 void SetBuildLog(BuildLog* log) { 213 scan_.set_build_log(log); 214 } 215 216 /// Load the dyndep information provided by the given node. 217 bool LoadDyndeps(Node* node, std::string* err); 218 219 State* state_; 220 const BuildConfig& config_; 221 Plan plan_; 222 std::unique_ptr<CommandRunner> command_runner_; 223 Status* status_; 224 225 private: 226 bool ExtractDeps(CommandRunner::Result* result, const std::string& deps_type, 227 const std::string& deps_prefix, 228 std::vector<Node*>* deps_nodes, std::string* err); 229 230 /// Map of running edge to time the edge started running. 231 typedef std::map<const Edge*, int> RunningEdgeMap; 232 RunningEdgeMap running_edges_; 233 234 /// Time the build started. 235 int64_t start_time_millis_; 236 237 std::string lock_file_path_; 238 DiskInterface* disk_interface_; 239 DependencyScan scan_; 240 241 // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr. 242 Builder(const Builder &other); // DO NOT IMPLEMENT 243 void operator=(const Builder &other); // DO NOT IMPLEMENT 244 }; 245 246 #endif // NINJA_BUILD_H_ 247