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