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
30struct BuildLog;
31struct Builder;
32struct DiskInterface;
33struct Edge;
34struct Explanations;
35struct Node;
36struct State;
37struct Status;
38
39/// Plan stores the state of a build plan: what we intend to build,
40/// which steps we're ready to execute.
41struct 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
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
101private:
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
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
145struct 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.
177 BuildConfig() = default;
178
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
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.
197struct 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.
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)
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
@ 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
Node * AddTarget(const std::string &name, std::string *err)
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
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 std::vector< Edge * > GetActiveEdges()
Definition build.h:166
virtual bool WaitForCommand(Result *result)=0
Wait for a command to complete, or return false if interrupted.
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
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.
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