Ninja
graph.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_GRAPH_H_
16 #define NINJA_GRAPH_H_
17 
18 #include <string>
19 #include <vector>
20 using namespace std;
21 
22 #include "eval_env.h"
23 #include "timestamp.h"
24 #include "util.h"
25 
26 struct BuildLog;
28 struct DiskInterface;
29 struct DepsLog;
30 struct Edge;
31 struct Node;
32 struct Pool;
33 struct State;
34 
35 /// Information about a node in the dependency graph: the file, whether
36 /// it's dirty, mtime, etc.
37 struct Node {
38  Node(const string& path, uint64_t slash_bits)
39  : path_(path),
40  slash_bits_(slash_bits),
41  mtime_(-1),
42  dirty_(false),
43  in_edge_(NULL),
44  id_(-1) {}
45 
46  /// Return false on error.
47  bool Stat(DiskInterface* disk_interface, string* err);
48 
49  /// Return false on error.
50  bool StatIfNecessary(DiskInterface* disk_interface, string* err) {
51  if (status_known())
52  return true;
53  return Stat(disk_interface, err);
54  }
55 
56  /// Mark as not-yet-stat()ed and not dirty.
57  void ResetState() {
58  mtime_ = -1;
59  dirty_ = false;
60  }
61 
62  /// Mark the Node as already-stat()ed and missing.
63  void MarkMissing() {
64  mtime_ = 0;
65  }
66 
67  bool exists() const {
68  return mtime_ != 0;
69  }
70 
71  bool status_known() const {
72  return mtime_ != -1;
73  }
74 
75  const string& path() const { return path_; }
76  /// Get |path()| but use slash_bits to convert back to original slash styles.
77  string PathDecanonicalized() const {
78  return PathDecanonicalized(path_, slash_bits_);
79  }
80  static string PathDecanonicalized(const string& path,
81  uint64_t slash_bits);
82  uint64_t slash_bits() const { return slash_bits_; }
83 
84  TimeStamp mtime() const { return mtime_; }
85 
86  bool dirty() const { return dirty_; }
87  void set_dirty(bool dirty) { dirty_ = dirty; }
88  void MarkDirty() { dirty_ = true; }
89 
90  Edge* in_edge() const { return in_edge_; }
91  void set_in_edge(Edge* edge) { in_edge_ = edge; }
92 
93  int id() const { return id_; }
94  void set_id(int id) { id_ = id; }
95 
96  const vector<Edge*>& out_edges() const { return out_edges_; }
97  void AddOutEdge(Edge* edge) { out_edges_.push_back(edge); }
98 
99  void Dump(const char* prefix="") const;
100 
101 private:
102  string path_;
103 
104  /// Set bits starting from lowest for backslashes that were normalized to
105  /// forward slashes by CanonicalizePath. See |PathDecanonicalized|.
107 
108  /// Possible values of mtime_:
109  /// -1: file hasn't been examined
110  /// 0: we looked, and file doesn't exist
111  /// >0: actual file's mtime
113 
114  /// Dirty is true when the underlying file is out-of-date.
115  /// But note that Edge::outputs_ready_ is also used in judging which
116  /// edges to build.
117  bool dirty_;
118 
119  /// The Edge that produces this Node, or NULL when there is no
120  /// known edge to produce it.
122 
123  /// All Edges that use this Node as an input.
124  vector<Edge*> out_edges_;
125 
126  /// A dense integer id for the node, assigned and used by DepsLog.
127  int id_;
128 };
129 
130 /// An edge in the dependency graph; links between Nodes using Rules.
131 struct Edge {
132  enum VisitMark {
135  VisitDone
136  };
137 
138  Edge() : rule_(NULL), pool_(NULL), env_(NULL), mark_(VisitNone),
139  outputs_ready_(false), deps_missing_(false),
140  implicit_deps_(0), order_only_deps_(0), implicit_outs_(0) {}
141 
142  /// Return true if all inputs' in-edges are ready.
143  bool AllInputsReady() const;
144 
145  /// Expand all variables in a command and return it as a string.
146  /// If incl_rsp_file is enabled, the string will also contain the
147  /// full contents of a response file (if applicable)
148  string EvaluateCommand(bool incl_rsp_file = false);
149 
150  /// Returns the shell-escaped value of |key|.
151  string GetBinding(const string& key);
152  bool GetBindingBool(const string& key);
153 
154  /// Like GetBinding("depfile"), but without shell escaping.
155  string GetUnescapedDepfile();
156  /// Like GetBinding("rspfile"), but without shell escaping.
157  string GetUnescapedRspfile();
158 
159  void Dump(const char* prefix="") const;
160 
161  const Rule* rule_;
163  vector<Node*> inputs_;
164  vector<Node*> outputs_;
169 
170  const Rule& rule() const { return *rule_; }
171  Pool* pool() const { return pool_; }
172  int weight() const { return 1; }
173  bool outputs_ready() const { return outputs_ready_; }
174 
175  // There are three types of inputs.
176  // 1) explicit deps, which show up as $in on the command line;
177  // 2) implicit deps, which the target depends on implicitly (e.g. C headers),
178  // and changes in them cause the target to rebuild;
179  // 3) order-only deps, which are needed before the target builds but which
180  // don't cause the target to rebuild.
181  // These are stored in inputs_ in that order, and we keep counts of
182  // #2 and #3 when we need to access the various subsets.
185  bool is_implicit(size_t index) {
186  return index >= inputs_.size() - order_only_deps_ - implicit_deps_ &&
187  !is_order_only(index);
188  }
189  bool is_order_only(size_t index) {
190  return index >= inputs_.size() - order_only_deps_;
191  }
192 
193  // There are two types of outputs.
194  // 1) explicit outs, which show up as $out on the command line;
195  // 2) implicit outs, which the target generates but are not part of $out.
196  // These are stored in outputs_ in that order, and we keep a count of
197  // #2 to use when we need to access the various subsets.
199  bool is_implicit_out(size_t index) const {
200  return index >= outputs_.size() - implicit_outs_;
201  }
202 
203  bool is_phony() const;
204  bool use_console() const;
205  bool maybe_phonycycle_diagnostic() const;
206 };
207 
208 
209 /// ImplicitDepLoader loads implicit dependencies, as referenced via the
210 /// "depfile" attribute in build files.
212  ImplicitDepLoader(State* state, DepsLog* deps_log,
213  DiskInterface* disk_interface,
214  DepfileParserOptions const* depfile_parser_options)
215  : state_(state), disk_interface_(disk_interface), deps_log_(deps_log),
216  depfile_parser_options_(depfile_parser_options) {}
217 
218  /// Load implicit dependencies for \a edge.
219  /// @return false on error (without filling \a err if info is just missing
220  // or out of date).
221  bool LoadDeps(Edge* edge, string* err);
222 
223  DepsLog* deps_log() const {
224  return deps_log_;
225  }
226 
227  private:
228  /// Load implicit dependencies for \a edge from a depfile attribute.
229  /// @return false on error (without filling \a err if info is just missing).
230  bool LoadDepFile(Edge* edge, const string& path, string* err);
231 
232  /// Load implicit dependencies for \a edge from the DepsLog.
233  /// @return false on error (without filling \a err if info is just missing).
234  bool LoadDepsFromLog(Edge* edge, string* err);
235 
236  /// Preallocate \a count spaces in the input array on \a edge, returning
237  /// an iterator pointing at the first new space.
238  vector<Node*>::iterator PreallocateSpace(Edge* edge, int count);
239 
240  /// If we don't have a edge that generates this input already,
241  /// create one; this makes us not abort if the input is missing,
242  /// but instead will rebuild in that circumstance.
243  void CreatePhonyInEdge(Node* node);
244 
249 };
250 
251 
252 /// DependencyScan manages the process of scanning the files in a graph
253 /// and updating the dirty/outputs_ready state of all the nodes and edges.
255  DependencyScan(State* state, BuildLog* build_log, DepsLog* deps_log,
256  DiskInterface* disk_interface,
257  DepfileParserOptions const* depfile_parser_options)
258  : build_log_(build_log),
259  disk_interface_(disk_interface),
260  dep_loader_(state, deps_log, disk_interface, depfile_parser_options) {}
261 
262  /// Update the |dirty_| state of the given node by inspecting its input edge.
263  /// Examine inputs, outputs, and command lines to judge whether an edge
264  /// needs to be re-run, and update outputs_ready_ and each outputs' |dirty_|
265  /// state accordingly.
266  /// Returns false on failure.
267  bool RecomputeDirty(Node* node, string* err);
268 
269  /// Recompute whether any output of the edge is dirty, if so sets |*dirty|.
270  /// Returns false on failure.
271  bool RecomputeOutputsDirty(Edge* edge, Node* most_recent_input,
272  bool* dirty, string* err);
273 
274  BuildLog* build_log() const {
275  return build_log_;
276  }
277  void set_build_log(BuildLog* log) {
278  build_log_ = log;
279  }
280 
281  DepsLog* deps_log() const {
282  return dep_loader_.deps_log();
283  }
284 
285  private:
286  bool RecomputeDirty(Node* node, vector<Node*>* stack, string* err);
287  bool VerifyDAG(Node* node, vector<Node*>* stack, string* err);
288 
289  /// Recompute whether a given single output should be marked dirty.
290  /// Returns true if so.
291  bool RecomputeOutputDirty(Edge* edge, Node* most_recent_input,
292  const string& command, Node* output);
293 
297 };
298 
299 #endif // NINJA_GRAPH_H_
const vector< Edge * > & out_edges() const
Definition: graph.h:96
int order_only_deps_
Definition: graph.h:184
int implicit_deps_
Definition: graph.h:183
DepsLog * deps_log() const
Definition: graph.h:223
const string & path() const
Definition: graph.h:75
VisitMark mark_
Definition: graph.h:166
Edge * in_edge() const
Definition: graph.h:90
DepfileParserOptions const * depfile_parser_options_
Definition: graph.h:248
void set_dirty(bool dirty)
Definition: graph.h:87
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:37
bool outputs_ready() const
Definition: graph.h:173
ImplicitDepLoader dep_loader_
Definition: graph.h:296
Interface for accessing the disk.
uint64_t slash_bits() const
Definition: graph.h:82
bool is_implicit_out(size_t index) const
Definition: graph.h:199
void AddOutEdge(Edge *edge)
Definition: graph.h:97
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:131
Edge * in_edge_
The Edge that produces this Node, or NULL when there is no known edge to produce it.
Definition: graph.h:121
Store a log of every command ran for every build.
Definition: build_log.h:42
bool is_order_only(size_t index)
Definition: graph.h:189
int id() const
Definition: graph.h:93
void MarkDirty()
Definition: graph.h:88
int weight() const
Definition: graph.h:172
vector< Edge * > out_edges_
All Edges that use this Node as an input.
Definition: graph.h:124
vector< Node * > inputs_
Definition: graph.h:163
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
An Env which contains a mapping of variables to values as well as a pointer to a parent scope...
Definition: eval_env.h:77
bool outputs_ready_
Definition: graph.h:167
bool is_implicit(size_t index)
Definition: graph.h:185
void set_id(int id)
Definition: graph.h:94
DiskInterface * disk_interface_
Definition: graph.h:295
DepsLog * deps_log_
Definition: graph.h:247
BindingEnv * env_
Definition: graph.h:165
An invokable build command and associated metadata (description, etc.).
Definition: eval_env.h:55
void ResetState()
Mark as not-yet-stat()ed and not dirty.
Definition: graph.h:57
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:63
bool dirty() const
Definition: graph.h:86
Node(const string &path, uint64_t slash_bits)
Definition: graph.h:38
uint64_t slash_bits_
Set bits starting from lowest for backslashes that were normalized to forward slashes by Canonicalize...
Definition: graph.h:106
BuildLog * build_log_
Definition: graph.h:294
string PathDecanonicalized() const
Get |path()| but use slash_bits to convert back to original slash styles.
Definition: graph.h:77
ImplicitDepLoader(State *state, DepsLog *deps_log, DiskInterface *disk_interface, DepfileParserOptions const *depfile_parser_options)
Definition: graph.h:212
DepsLog * deps_log() const
Definition: graph.h:281
BuildLog * build_log() const
Definition: graph.h:274
Edge()
Definition: graph.h:138
int implicit_outs_
Definition: graph.h:198
int64_t TimeStamp
Definition: timestamp.h:31
A pool for delayed edges.
Definition: state.h:40
void set_build_log(BuildLog *log)
Definition: graph.h:277
TimeStamp mtime_
Possible values of mtime_: -1: file hasn&#39;t been examined 0: we looked, and file doesn&#39;t exist >0: act...
Definition: graph.h:112
bool status_known() const
Definition: graph.h:71
bool dirty_
Dirty is true when the underlying file is out-of-date.
Definition: graph.h:117
int id_
A dense integer id for the node, assigned and used by DepsLog.
Definition: graph.h:127
Pool * pool_
Definition: graph.h:162
TimeStamp mtime() const
Definition: graph.h:84
DependencyScan manages the process of scanning the files in a graph and updating the dirty/outputs_re...
Definition: graph.h:254
const Rule * rule_
Definition: graph.h:161
ImplicitDepLoader loads implicit dependencies, as referenced via the "depfile" attribute in build fil...
Definition: graph.h:211
VisitMark
Definition: graph.h:132
const Rule & rule() const
Definition: graph.h:170
Pool * pool() const
Definition: graph.h:171
State * state_
Definition: graph.h:245
Global state (file status) for a single run.
Definition: state.h:85
void set_in_edge(Edge *edge)
Definition: graph.h:91
unsigned long long uint64_t
Definition: win32port.h:29
DiskInterface * disk_interface_
Definition: graph.h:246
string path_
Definition: graph.h:102
bool exists() const
Definition: graph.h:67
bool deps_missing_
Definition: graph.h:168
DependencyScan(State *state, BuildLog *build_log, DepsLog *deps_log, DiskInterface *disk_interface, DepfileParserOptions const *depfile_parser_options)
Definition: graph.h:255
bool StatIfNecessary(DiskInterface *disk_interface, string *err)
Return false on error.
Definition: graph.h:50
vector< Node * > outputs_
Definition: graph.h:164