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. |
53 | 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. |
74 | 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 { |
137 | 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 { |
143 | Result() : edge(NULL) {} |
144 | Edge* edge; |
145 | ExitStatus status; |
146 | std::string output; |
147 | 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 | |
152 | virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); } |
153 | virtual void Abort() {} |
154 | }; |
155 | |
156 | /// Options (e.g. verbosity, parallelism) passed to a build. |
157 | struct BuildConfig { |
158 | 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. |
208 | 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 | 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 | |