Ninja
build.h
Go to the documentation of this file.
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 {
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.
101  /// We want to build the edge, but have not yet scheduled it.
103  /// We want to build the edge, have scheduled it, and are waiting
104  /// for it to complete.
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 
123 
125 
126  /// Total number of edges that have commands (not phony).
128 
129  /// Total remaining number of 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.
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) {}
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 {
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
166  };
168  bool dry_run;
171  /// The maximum load average we must not exceed. A negative value
172  /// means that we do not have any limit.
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 
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
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;
233 
234  /// Time the build started.
236 
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_
bool Build(std::string *err)
Run the build.
Definition: build.cc:599
bool RefreshDyndepDependents(DependencyScan *scan, const Node *node, std::string *err)
Definition: build.cc:373
Status * status_
Definition: build.h:223
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:136
std::auto_ptr< CommandRunner > command_runner_
Definition: build.h:219
Verbosity verbosity
Definition: build.h:167
We do not want to build the edge, but we might want to build one of its dependents.
Definition: build.h:100
Builder * builder_
Definition: build.h:124
Store data loaded from one dyndep file.
Definition: dyndep.h:40
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:173
Plan stores the state of a build plan: what we intend to build, which steps we&#39;re ready to execute...
Definition: build.h:40
BuildConfig()
Definition: build.h:158
RunningEdgeMap running_edges_
Definition: build.h:232
The result of waiting for a command.
Definition: build.h:142
EdgeSet ready_
Definition: build.h:122
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:39
Edge * FindWork()
Definition: build.cc:151
virtual bool CanRunMore() const =0
bool DyndepsLoaded(DependencyScan *scan, const Node *node, const DyndepFile &ddf, std::string *err)
Update the build plan to account for modifications made to the graph by information loaded from a dyn...
Definition: build.cc:305
State * state_
Definition: build.h:215
std::string output
Definition: build.h:146
Interface for accessing the disk.
const BuildConfig & config_
Definition: build.h:216
Plan(Builder *builder=NULL)
Definition: build.cc:78
Builder(State *state, const BuildConfig &config, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface, Status *status, int64_t start_time_millis)
Definition: build.cc:513
bool StartEdge(Edge *edge, std::string *err)
Definition: build.cc:697
void Dump() const
Dumps the current state of the plan.
Definition: build.cc:440
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:74
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:164
virtual void Abort()
Definition: build.h:153
Store a log of every command ran for every build.
Definition: build_log.h:43
virtual std::vector< Edge * > GetActiveEdges()
Definition: build.h:152
DiskInterface * disk_interface_
Definition: build.h:237
std::map< const Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:231
std::map< Edge *, Want > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:120
void ScheduleWork(std::map< Edge *, Want >::iterator want_e)
Submits a ready edge as a candidate for execution.
Definition: build.cc:160
bool AddSubTarget(const Node *node, const Node *dependent, std::string *err, std::set< Edge *> *dyndep_walk)
Definition: build.cc:95
Want
Enumerate possible steps we want for an edge.
Definition: build.h:96
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:28
void operator=(const Builder &other)
int parallelism
Definition: build.h:169
int failures_allowed
Definition: build.h:170
~Builder()
Definition: build.cc:523
void Reset()
Reset state. Clears want and ready sets.
Definition: build.cc:84
bool ExtractDeps(CommandRunner::Result *result, const std::string &deps_type, const std::string &deps_prefix, std::vector< Node *> *deps_nodes, std::string *err)
Definition: build.cc:857
Node * AddTarget(const std::string &name, std::string *err)
ExitStatus
Definition: exit_status.h:18
Abstract interface to object that tracks the status of a build: completion fraction, printing updates.
Definition: status.h:26
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:130
ExitStatus status
Definition: build.h:145
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:527
void set_build_log(BuildLog *log)
Definition: graph.h:338
bool EdgeMaybeReady(std::map< Edge *, Want >::iterator want_e, std::string *err)
Definition: build.cc:233
We want to build the edge, but have not yet scheduled it.
Definition: build.h:102
int64_t start_time_millis_
Time the build started.
Definition: build.h:235
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:208
Builder wraps the build process: starting commands, updating status.
Definition: build.h:178
bool LoadDyndeps(Node *node, std::string *err)
Load the dyndep information provided by the given node.
Definition: build.cc:923
bool EdgeFinished(Edge *edge, EdgeResult result, std::string *err)
Mark an edge as done building (whether it succeeded or failed).
Definition: build.cc:182
bool AddTarget(const Node *target, std::string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:91
EdgeResult
Definition: build.h:58
bool NodeFinished(Node *node, std::string *err)
Update plan with knowledge that the given node is up to date.
Definition: build.cc:210
Plan plan_
Definition: build.h:217
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:312
void EdgeWanted(const Edge *edge)
Definition: build.cc:145
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:157
Global state (file status) for a single run.
Definition: state.h:92
We want to build the edge, have scheduled it, and are waiting for it to complete. ...
Definition: build.h:105
bool CleanNode(DependencyScan *scan, Node *node, std::string *err)
Clean the given node during the build.
Definition: build.cc:248
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual ~CommandRunner()
Definition: build.h:137
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:53
bool success() const
Definition: build.h:147
DepfileParserOptions depfile_parser_options
Definition: build.h:174
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:595
bool dry_run
Definition: build.h:168
DependencyScan scan_
Definition: build.h:238
std::set< Edge *, EdgeCmp > EdgeSet
Definition: graph.h:259
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:127
void UnmarkDependents(const Node *node, std::set< Node *> *dependents)
Definition: build.cc:420
bool FinishCommand(CommandRunner::Result *result, std::string *err)
Update status ninja logs following a command termination.
Definition: build.cc:733
virtual bool StartCommand(Edge *edge)=0