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 <string>
22 #include <vector>
23 
24 #include "depfile_parser.h"
25 #include "exit_status.h"
26 #include "graph.h"
27 #include "jobserver.h"
28 #include "util.h" // int64_t
29 
30 struct BuildLog;
31 struct Builder;
32 struct DiskInterface;
33 struct Edge;
34 struct Explanations;
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.
54  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 {
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.
75  int command_edge_count() const { return command_edges_; }
76 
77  /// Reset state. Clears want and ready sets.
78  void Reset();
79 
80  // After all targets have been added, prepares the ready queue for find work.
81  void PrepareQueue();
82 
83  /// Update the build plan to account for modifications made to the graph
84  /// by information loaded from a dyndep file.
85  bool DyndepsLoaded(DependencyScan* scan, const Node* node,
86  const DyndepFile& ddf, std::string* err);
87 
88  /// Enumerate possible steps we want for an edge.
89  enum Want
90  {
91  /// We do not want to build the edge, but we might want to build one of
92  /// its dependents.
94  /// We want to build the edge, but have not yet scheduled it.
96  /// We want to build the edge, have scheduled it, and are waiting
97  /// for it to complete.
99  };
100 
101 private:
102  void ComputeCriticalPath();
103  bool RefreshDyndepDependents(DependencyScan* scan, const Node* node, std::string* err);
104  void UnmarkDependents(const Node* node, std::set<Node*>* dependents);
105  bool AddSubTarget(const Node* node, const Node* dependent, std::string* err,
106  std::set<Edge*>* dyndep_walk);
107 
108  // Add edges that kWantToStart into the ready queue
109  // Must be called after ComputeCriticalPath and before FindWork
110  void ScheduleInitialEdges();
111 
112  /// Update plan with knowledge that the given node is up to date.
113  /// If the node is a dyndep binding on any of its dependents, this
114  /// loads dynamic dependencies from the node's path.
115  /// Returns 'false' if loading dyndep info fails and 'true' otherwise.
116  bool NodeFinished(Node* node, std::string* err);
117 
118  void EdgeWanted(const Edge* edge);
119  bool EdgeMaybeReady(std::map<Edge*, Want>::iterator want_e, std::string* err);
120 
121  /// Submits a ready edge as a candidate for execution.
122  /// The edge may be delayed from running, for example if it's a member of a
123  /// currently-full pool.
124  void ScheduleWork(std::map<Edge*, Want>::iterator want_e);
125 
126  /// Keep track of which edges we want to build in this plan. If this map does
127  /// not contain an entry for an edge, we do not want to build the entry or its
128  /// dependents. If it does contain an entry, the enumeration indicates what
129  /// we want for the edge.
130  std::map<Edge*, Want> want_;
131 
133 
135  /// user provided targets in build order, earlier one have higher priority
136  std::vector<const Node*> targets_;
137 
138  /// Total number of edges that have commands (not phony).
140 
141  /// Total remaining number of wanted edges.
143 };
144 
145 struct BuildConfig;
146 
147 /// CommandRunner is an interface that wraps running the build
148 /// subcommands. This allows tests to abstract out running commands.
149 /// RealCommandRunner is an implementation that actually runs commands.
151  virtual ~CommandRunner() {}
152  virtual size_t CanRunMore() const = 0;
153  virtual bool StartCommand(Edge* edge) = 0;
154 
155  /// The result of waiting for a command.
156  struct Result {
157  Result() : edge(NULL) {}
160  std::string output;
161  bool success() const { return status == ExitSuccess; }
162  };
163  /// Wait for a command to complete, or return false if interrupted.
164  virtual bool WaitForCommand(Result* result) = 0;
165 
166  virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
167  virtual void Abort() {}
168 
169  /// Creates the RealCommandRunner. \arg jobserver can be nullptr if there
170  /// is no jobserver pool to use.
171  static CommandRunner* factory(const BuildConfig& config,
172  Jobserver::Client* jobserver);
173 };
174 
175 /// Options (e.g. verbosity, parallelism) passed to a build.
176 struct BuildConfig {
177  BuildConfig() = default;
178 
179  enum Verbosity {
180  QUIET, // No output -- used when testing.
181  NO_STATUS_UPDATE, // just regular output but suppress status update
182  NORMAL, // regular output and status update
183  VERBOSE
184  };
186  bool dry_run = false;
187  int parallelism = 1;
190  /// The maximum load average we must not exceed. A negative value
191  /// means that we do not have any limit.
192  double max_load_average = -0.0f;
194 };
195 
196 /// Builder wraps the build process: starting commands, updating status.
197 struct Builder {
198  Builder(State* state, const BuildConfig& config, BuildLog* build_log,
199  DepsLog* deps_log, DiskInterface* disk_interface, Status* status,
200  int64_t start_time_millis);
201  ~Builder();
202 
203  /// Set Jobserver client instance for this builder.
204  void SetJobserverClient(std::unique_ptr<Jobserver::Client> jobserver_client) {
205  jobserver_ = std::move(jobserver_client);
206  }
207 
208  /// Clean up after interrupted commands by deleting output files.
209  void Cleanup();
210 
211  Node* AddTarget(const std::string& name, std::string* err);
212 
213  /// Add a target to the build, scanning dependencies.
214  /// @return false on error.
215  bool AddTarget(Node* target, std::string* err);
216 
217  /// Returns true if the build targets are already up to date.
218  bool AlreadyUpToDate() const;
219 
220  /// Run the build. Returns ExitStatus or the exit code of the last failed job.
221  /// It is an error to call this function when AlreadyUpToDate() is true.
222  ExitStatus Build(std::string* err);
223 
224  bool StartEdge(Edge* edge, std::string* err);
225 
226  /// Update status ninja logs following a command termination.
227  /// @return false if the build can not proceed further due to a fatal error.
228  bool FinishCommand(CommandRunner::Result* result, std::string* err);
229 
230  /// Used for tests.
231  void SetBuildLog(BuildLog* log) {
232  scan_.set_build_log(log);
233  }
234 
235  /// Load the dyndep information provided by the given node.
236  bool LoadDyndeps(Node* node, std::string* err);
237 
241  std::unique_ptr<Jobserver::Client> jobserver_;
242  std::unique_ptr<CommandRunner> command_runner_;
244 
245  /// Returns ExitStatus or the exit code of the last failed job
246  /// (doesn't need to be an enum value of ExitStatus)
247  ExitStatus GetExitCode() const { return exit_code_; }
248 
249  private:
250  bool ExtractDeps(CommandRunner::Result* result, const std::string& deps_type,
251  const std::string& deps_prefix,
252  std::vector<Node*>* deps_nodes, std::string* err);
253 
254  /// Map of running edge to time the edge started running.
255  typedef std::map<const Edge*, int> RunningEdgeMap;
257 
258  /// Time the build started.
260 
261  std::string lock_file_path_;
263 
264  // Only create an Explanations class if '-d explain' is used.
265  std::unique_ptr<Explanations> explanations_;
266 
268 
269  /// Keep the global exit code for the build
271  void SetFailureCode(ExitStatus code);
272 
273  // Unimplemented copy ctor and operator= ensure we don't copy the auto_ptr.
274  Builder(const Builder &other); // DO NOT IMPLEMENT
275  void operator=(const Builder &other); // DO NOT IMPLEMENT
276 };
277 
278 #endif // NINJA_BUILD_H_
A Jobserver::Client instance models a client of an external GNU jobserver pool, which can be implemen...
Definition: jobserver.h:189
ExitStatus
Definition: exit_status.h:27
@ ExitSuccess
Definition: exit_status.h:28
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:176
int failures_allowed
Definition: build.h:189
DepfileParserOptions depfile_parser_options
Definition: build.h:193
@ VERBOSE
Definition: build.h:183
@ NORMAL
Definition: build.h:182
@ NO_STATUS_UPDATE
Definition: build.h:181
double max_load_average
The maximum load average we must not exceed.
Definition: build.h:192
BuildConfig()=default
bool dry_run
Definition: build.h:186
bool disable_jobserver_client
Definition: build.h:188
Verbosity verbosity
Definition: build.h:185
int parallelism
Definition: build.h:187
Store a log of every command ran for every build.
Definition: build_log.h:45
Builder wraps the build process: starting commands, updating status.
Definition: build.h:197
std::unique_ptr< Jobserver::Client > jobserver_
Definition: build.h:241
void SetJobserverClient(std::unique_ptr< Jobserver::Client > jobserver_client)
Set Jobserver client instance for this builder.
Definition: build.h:204
std::map< const Edge *, int > RunningEdgeMap
Map of running edge to time the edge started running.
Definition: build.h:255
std::string lock_file_path_
Definition: build.h:261
State * state_
Definition: build.h:238
Plan plan_
Definition: build.h:240
void SetFailureCode(ExitStatus code)
Definition: build.cc:1063
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:607
Status * status_
Definition: build.h:243
void Cleanup()
Clean up after interrupted commands by deleting output files.
Definition: build.cc:627
bool AddTarget(Node *target, std::string *err)
Add a target to the build, scanning dependencies.
int64_t start_time_millis_
Time the build started.
Definition: build.h:259
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:984
bool FinishCommand(CommandRunner::Result *result, std::string *err)
Update status ninja logs following a command termination.
Definition: build.cc:876
ExitStatus GetExitCode() const
Returns ExitStatus or the exit code of the last failed job (doesn't need to be an enum value of ExitS...
Definition: build.h:247
~Builder()
Definition: build.cc:622
RunningEdgeMap running_edges_
Definition: build.h:256
const BuildConfig & config_
Definition: build.h:239
void operator=(const Builder &other)
DiskInterface * disk_interface_
Definition: build.h:262
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:699
ExitStatus Build(std::string *err)
Run the build.
Definition: build.cc:703
bool StartEdge(Edge *edge, std::string *err)
Definition: build.cc:823
std::unique_ptr< CommandRunner > command_runner_
Definition: build.h:242
ExitStatus exit_code_
Keep the global exit code for the build.
Definition: build.h:270
Builder(const Builder &other)
std::unique_ptr< Explanations > explanations_
Definition: build.h:265
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:231
DependencyScan scan_
Definition: build.h:267
bool LoadDyndeps(Node *node, std::string *err)
Load the dyndep information provided by the given node.
Definition: build.cc:1050
Node * AddTarget(const std::string &name, std::string *err)
The result of waiting for a command.
Definition: build.h:156
ExitStatus status
Definition: build.h:159
bool success() const
Definition: build.h:161
std::string output
Definition: build.h:160
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:150
virtual bool StartCommand(Edge *edge)=0
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
virtual std::vector< Edge * > GetActiveEdges()
Definition: build.h:166
virtual size_t CanRunMore() const =0
virtual void Abort()
Definition: build.h:167
static CommandRunner * factory(const BuildConfig &config, Jobserver::Client *jobserver)
Creates the RealCommandRunner.
virtual ~CommandRunner()
Definition: build.h:151
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:332
void set_build_log(BuildLog *log)
Definition: graph.h:359
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
Interface for accessing the disk.
Store data loaded from one dyndep file.
Definition: dyndep.h:42
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:175
A class used to record a list of explanation strings associated with a given 'item' pointer.
Definition: explanations.h:27
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
Definition: graph.h:42
Plan stores the state of a build plan: what we intend to build, which steps we're ready to execute.
Definition: build.h:41
bool AddSubTarget(const Node *node, const Node *dependent, std::string *err, std::set< Edge * > *dyndep_walk)
Definition: build.cc:99
int command_edge_count() const
Number of edges with commands to run.
Definition: build.h:75
int command_edges_
Total number of edges that have commands (not phony).
Definition: build.h:139
void Reset()
Reset state. Clears want and ready sets.
Definition: build.cc:87
bool EdgeMaybeReady(std::map< Edge *, Want >::iterator want_e, std::string *err)
Definition: build.cc:256
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:331
void ScheduleInitialEdges()
Definition: build.cc:563
bool AddTarget(const Node *target, std::string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:94
bool more_to_do() const
Returns true if there's more work to be done.
Definition: build.h:54
int wanted_edges_
Total remaining number of wanted edges.
Definition: build.h:142
void Dump() const
Dumps the current state of the plan.
Definition: build.cc:597
Builder * builder_
Definition: build.h:134
bool RefreshDyndepDependents(DependencyScan *scan, const Node *node, std::string *err)
Definition: build.cc:399
void PrepareQueue()
Definition: build.cc:592
Want
Enumerate possible steps we want for an edge.
Definition: build.h:90
@ kWantNothing
We do not want to build the edge, but we might want to build one of its dependents.
Definition: build.h:93
@ kWantToFinish
We want to build the edge, have scheduled it, and are waiting for it to complete.
Definition: build.h:98
@ kWantToStart
We want to build the edge, but have not yet scheduled it.
Definition: build.h:95
void ScheduleWork(std::map< Edge *, Want >::iterator want_e)
Submits a ready edge as a candidate for execution.
Definition: build.cc:179
std::map< Edge *, Want > want_
Keep track of which edges we want to build in this plan.
Definition: build.h:130
EdgePriorityQueue ready_
Definition: build.h:132
void ComputeCriticalPath()
Definition: build.cc:476
void EdgeWanted(const Edge *edge)
Definition: build.cc:152
std::vector< const Node * > targets_
user provided targets in build order, earlier one have higher priority
Definition: build.h:136
void UnmarkDependents(const Node *node, std::set< Node * > *dependents)
Definition: build.cc:446
bool EdgeFinished(Edge *edge, EdgeResult result, std::string *err)
Mark an edge as done building (whether it succeeded or failed).
Definition: build.cc:201
EdgeResult
Definition: build.h:59
@ kEdgeSucceeded
Definition: build.h:61
@ kEdgeFailed
Definition: build.h:60
Edge * FindWork()
Definition: build.cc:161
Plan(Builder *builder=NULL)
Definition: build.cc:81
bool CleanNode(DependencyScan *scan, Node *node, std::string *err)
Clean the given node during the build.
Definition: build.cc:271
bool NodeFinished(Node *node, std::string *err)
Update plan with knowledge that the given node is up to date.
Definition: build.cc:233
Global state (file status) for a single run.
Definition: state.h:95
Abstract interface to object that tracks the status of a build: completion fraction,...
Definition: status.h:27
signed long long int64_t
A 64-bit integer type.
Definition: win32port.h:28