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
30struct BuildLog;
31struct Builder;
32struct DiskInterface;
33struct Edge;
34struct Node;
35struct State;
36struct Status;
37
38/// Plan stores the state of a build plan: what we intend to build,
39/// which steps we're ready to execute.
40struct 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);
83private:
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.
136struct 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.
157struct 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.
178struct 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