• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <queue>
24 
25 #include "depfile_parser.h"
26 #include "graph.h"  // XXX needed for DependencyScan; should rearrange.
27 #include "graph.h"
28 #include "exit_status.h"
29 #include "util.h"  // int64_t
30 
31 struct BuildLog;
32 struct Builder;
33 struct DiskInterface;
34 struct Edge;
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.
more_to_doPlan54     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 {
60         kEdgeFailed,
61         kEdgeSucceeded
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.
command_edge_countPlan75     int command_edge_count() const { return command_edges_; }
76 
77     /// Reset state.  Clears want and ready sets.
78     void Reset();
79 
80     /// Update the build plan to account for modifications made to the graph
81     /// by information loaded from a dyndep file.
82     bool DyndepsLoaded(DependencyScan* scan, const Node* node,
83                                           const DyndepFile& ddf, std::string* err);
84 
85 private:
86     bool RefreshDyndepDependents(DependencyScan* scan, const Node* node, std::string* err);
87     void UnmarkDependents(const Node* node, std::set<Node*>* dependents);
88     bool AddSubTarget(const Node* node, const Node* dependent, std::string* err,
89                                         std::set<Edge*>* dyndep_walk);
90 
91     /// Update plan with knowledge that the given node is up to date.
92     /// If the node is a dyndep binding on any of its dependents, this
93     /// loads dynamic dependencies from the node's path.
94     /// Returns 'false' if loading dyndep info fails and 'true' otherwise.
95     bool NodeFinished(Node* node, std::string* err);
96 
97     /// Enumerate possible steps we want for an edge.
98     enum Want
99     {
100         /// We do not want to build the edge, but we might want to build one of
101         /// its dependents.
102         kWantNothing,
103         /// We want to build the edge, but have not yet scheduled it.
104         kWantToStart,
105         /// We want to build the edge, have scheduled it, and are waiting
106         /// for it to complete.
107         kWantToFinish
108     };
109 
110     void EdgeWanted(const Edge* edge);
111     bool EdgeMaybeReady(std::map<Edge*, Want>::iterator want_e, std::string* err);
112 
113     /// Submits a ready edge as a candidate for execution.
114     /// The edge may be delayed from running, for example if it's a member of a
115     /// currently-full pool.
116     void ScheduleWork(std::map<Edge*, Want>::iterator want_e);
117 
118     /// Keep track of which edges we want to build in this plan.  If this map does
119     /// not contain an entry for an edge, we do not want to build the entry or its
120     /// dependents.  If it does contain an entry, the enumeration indicates what
121     /// we want for the edge.
122     std::map<Edge*, Want> want_;
123 
124     EdgeSet ready_;
125 
126     Builder* builder_;
127 
128     /// Total number of edges that have commands (not phony).
129     int command_edges_;
130 
131     /// Total remaining number of wanted edges.
132     int wanted_edges_;
133 };
134 
135 /// CommandRunner is an interface that wraps running the build
136 /// subcommands.  This allows tests to abstract out running commands.
137 /// RealCommandRunner is an implementation that actually runs commands.
138 struct CommandRunner {
~CommandRunnerCommandRunner139     virtual ~CommandRunner() {}
140     virtual size_t CanRunMore() const = 0;
141     virtual bool StartCommand(Edge* edge) = 0;
142 
143     /// The result of waiting for a command.
144     struct Result {
ResultCommandRunner::Result145         Result() : edge(NULL) {}
146         Edge* edge;
147         ExitStatus status;
148         std::string output;
successCommandRunner::Result149         bool success() const { return status == ExitSuccess; }
150     };
151     /// Wait for a command to complete, or return false if interrupted.
152     virtual bool WaitForCommand(Result* result) = 0;
153 
GetActiveEdgesCommandRunner154     virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
AbortCommandRunner155     virtual void Abort() {}
156 };
157 
158 /// Options (e.g. verbosity, parallelism) passed to a build.
159 struct BuildConfig {
BuildConfigBuildConfig160     BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
161                                     failures_allowed(1), max_load_average(-0.0f) {}
162 
163     enum Verbosity {
164         QUIET,  // No output -- used when testing.
165         NO_STATUS_UPDATE,  // just regular output but suppress status update
166         NORMAL,  // regular output and status update
167         VERBOSE
168     };
169     Verbosity verbosity;
170     bool dry_run;
171     int parallelism;
172     int failures_allowed;
173     /// The maximum load average we must not exceed. A negative value
174     /// means that we do not have any limit.
175     double max_load_average;
176     DepfileParserOptions depfile_parser_options;
177 };
178 
179 /// Builder wraps the build process: starting commands, updating status.
180 struct Builder {
181     Builder(State* state, const BuildConfig& config,
182                     BuildLog* build_log, DepsLog* deps_log,
183                     DiskInterface* disk_interface, Status* status,
184                     int64_t start_time_millis);
185     ~Builder();
186 
187     /// Clean up after interrupted commands by deleting output files.
188     void Cleanup();
189 
190     Node* AddTarget(const std::string& name, std::string* err);
191 
192     /// Add a target to the build, scanning dependencies.
193     /// @return false on error.
194     bool AddTarget(Node* target, std::string* err);
195 
196     /// Returns true if the build targets are already up to date.
197     bool AlreadyUpToDate() const;
198 
199     /// Run the build.  Returns false on error.
200     /// It is an error to call this function when AlreadyUpToDate() is true.
201     bool Build(std::string* err);
202 
203     bool StartEdge(Edge* edge, std::string* err);
204 
205     std::string GetContent(Edge* edge);
206 
207     /// Update status ninja logs following a command termination.
208     /// @return false if the build can not proceed further due to a fatal error.
209     bool FinishCommand(CommandRunner::Result* result, std::string* err);
210 
211     /// Used for tests.
SetBuildLogBuilder212     void SetBuildLog(BuildLog* log) {
213         scan_.set_build_log(log);
214     }
215 
216     /// Load the dyndep information provided by the given node.
217     bool LoadDyndeps(Node* node, std::string* err);
218 
219     State* state_;
220     const BuildConfig& config_;
221     Plan plan_;
222     std::unique_ptr<CommandRunner> command_runner_;
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