1695b41eeSopenharmony_ci// Copyright 2011 Google Inc. All Rights Reserved.
2695b41eeSopenharmony_ci//
3695b41eeSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4695b41eeSopenharmony_ci// you may not use this file except in compliance with the License.
5695b41eeSopenharmony_ci// You may obtain a copy of the License at
6695b41eeSopenharmony_ci//
7695b41eeSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8695b41eeSopenharmony_ci//
9695b41eeSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10695b41eeSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11695b41eeSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12695b41eeSopenharmony_ci// See the License for the specific language governing permissions and
13695b41eeSopenharmony_ci// limitations under the License.
14695b41eeSopenharmony_ci
15695b41eeSopenharmony_ci#ifndef NINJA_GRAPH_H_
16695b41eeSopenharmony_ci#define NINJA_GRAPH_H_
17695b41eeSopenharmony_ci
18695b41eeSopenharmony_ci#include <algorithm>
19695b41eeSopenharmony_ci#include <set>
20695b41eeSopenharmony_ci#include <string>
21695b41eeSopenharmony_ci#include <vector>
22695b41eeSopenharmony_ci
23695b41eeSopenharmony_ci#include "dyndep.h"
24695b41eeSopenharmony_ci#include "eval_env.h"
25695b41eeSopenharmony_ci#include "timestamp.h"
26695b41eeSopenharmony_ci#include "util.h"
27695b41eeSopenharmony_ci
28695b41eeSopenharmony_cistruct BuildLog;
29695b41eeSopenharmony_cistruct DepfileParserOptions;
30695b41eeSopenharmony_cistruct DiskInterface;
31695b41eeSopenharmony_cistruct DepsLog;
32695b41eeSopenharmony_cistruct Edge;
33695b41eeSopenharmony_cistruct Node;
34695b41eeSopenharmony_cistruct Pool;
35695b41eeSopenharmony_cistruct State;
36695b41eeSopenharmony_ci
37695b41eeSopenharmony_ci/// Information about a node in the dependency graph: the file, whether
38695b41eeSopenharmony_ci/// it's dirty, mtime, etc.
39695b41eeSopenharmony_cistruct Node {
40695b41eeSopenharmony_ci    Node(const std::string& path, uint64_t slash_bits)
41695b41eeSopenharmony_ci            : path_(path), slash_bits_(slash_bits) {}
42695b41eeSopenharmony_ci
43695b41eeSopenharmony_ci    /// Return false on error.
44695b41eeSopenharmony_ci    bool Stat(DiskInterface* disk_interface, std::string* err);
45695b41eeSopenharmony_ci
46695b41eeSopenharmony_ci    /// If the file doesn't exist, set the mtime_ from its dependencies
47695b41eeSopenharmony_ci    void UpdatePhonyMtime(TimeStamp mtime);
48695b41eeSopenharmony_ci
49695b41eeSopenharmony_ci    /// Return false on error.
50695b41eeSopenharmony_ci    bool StatIfNecessary(DiskInterface* disk_interface, std::string* err) {
51695b41eeSopenharmony_ci        if (status_known())
52695b41eeSopenharmony_ci            return true;
53695b41eeSopenharmony_ci        return Stat(disk_interface, err);
54695b41eeSopenharmony_ci    }
55695b41eeSopenharmony_ci
56695b41eeSopenharmony_ci    /// Mark as not-yet-stat()ed and not dirty.
57695b41eeSopenharmony_ci    void ResetState() {
58695b41eeSopenharmony_ci        mtime_ = -1;
59695b41eeSopenharmony_ci        exists_ = ExistenceStatusUnknown;
60695b41eeSopenharmony_ci        dirty_ = false;
61695b41eeSopenharmony_ci    }
62695b41eeSopenharmony_ci
63695b41eeSopenharmony_ci    /// Mark the Node as already-stat()ed and missing.
64695b41eeSopenharmony_ci    void MarkMissing() {
65695b41eeSopenharmony_ci        if (mtime_ == -1) {
66695b41eeSopenharmony_ci            mtime_ = 0;
67695b41eeSopenharmony_ci        }
68695b41eeSopenharmony_ci        exists_ = ExistenceStatusMissing;
69695b41eeSopenharmony_ci    }
70695b41eeSopenharmony_ci
71695b41eeSopenharmony_ci    bool exists() const {
72695b41eeSopenharmony_ci        return exists_ == ExistenceStatusExists;
73695b41eeSopenharmony_ci    }
74695b41eeSopenharmony_ci
75695b41eeSopenharmony_ci    bool status_known() const {
76695b41eeSopenharmony_ci        return exists_ != ExistenceStatusUnknown;
77695b41eeSopenharmony_ci    }
78695b41eeSopenharmony_ci
79695b41eeSopenharmony_ci    const std::string& path() const { return path_; }
80695b41eeSopenharmony_ci    /// Get |path()| but use slash_bits to convert back to original slash styles.
81695b41eeSopenharmony_ci    std::string PathDecanonicalized() const {
82695b41eeSopenharmony_ci        return PathDecanonicalized(path_, slash_bits_);
83695b41eeSopenharmony_ci    }
84695b41eeSopenharmony_ci    static std::string PathDecanonicalized(const std::string& path,
85695b41eeSopenharmony_ci                                                                                  uint64_t slash_bits);
86695b41eeSopenharmony_ci    uint64_t slash_bits() const { return slash_bits_; }
87695b41eeSopenharmony_ci
88695b41eeSopenharmony_ci    TimeStamp mtime() const { return mtime_; }
89695b41eeSopenharmony_ci
90695b41eeSopenharmony_ci    bool dirty() const { return dirty_; }
91695b41eeSopenharmony_ci    void set_dirty(bool dirty) { dirty_ = dirty; }
92695b41eeSopenharmony_ci    void MarkDirty() { dirty_ = true; }
93695b41eeSopenharmony_ci
94695b41eeSopenharmony_ci    bool dyndep_pending() const { return dyndep_pending_; }
95695b41eeSopenharmony_ci    void set_dyndep_pending(bool pending) { dyndep_pending_ = pending; }
96695b41eeSopenharmony_ci
97695b41eeSopenharmony_ci    Edge* in_edge() const { return in_edge_; }
98695b41eeSopenharmony_ci    void set_in_edge(Edge* edge) { in_edge_ = edge; }
99695b41eeSopenharmony_ci
100695b41eeSopenharmony_ci    /// Indicates whether this node was generated from a depfile or dyndep file,
101695b41eeSopenharmony_ci    /// instead of being a regular input or output from the Ninja manifest.
102695b41eeSopenharmony_ci    bool generated_by_dep_loader() const { return generated_by_dep_loader_; }
103695b41eeSopenharmony_ci
104695b41eeSopenharmony_ci    void set_generated_by_dep_loader(bool value) {
105695b41eeSopenharmony_ci        generated_by_dep_loader_ = value;
106695b41eeSopenharmony_ci    }
107695b41eeSopenharmony_ci
108695b41eeSopenharmony_ci    int id() const { return id_; }
109695b41eeSopenharmony_ci    void set_id(int id) { id_ = id; }
110695b41eeSopenharmony_ci
111695b41eeSopenharmony_ci    const std::vector<Edge*>& out_edges() const { return out_edges_; }
112695b41eeSopenharmony_ci    const std::vector<Edge*>& validation_out_edges() const { return validation_out_edges_; }
113695b41eeSopenharmony_ci    void AddOutEdge(Edge* edge) { out_edges_.push_back(edge); }
114695b41eeSopenharmony_ci    void AddValidationOutEdge(Edge* edge) { validation_out_edges_.push_back(edge); }
115695b41eeSopenharmony_ci
116695b41eeSopenharmony_ci    void Dump(const char* prefix="") const;
117695b41eeSopenharmony_ci
118695b41eeSopenharmony_ciprivate:
119695b41eeSopenharmony_ci    std::string path_;
120695b41eeSopenharmony_ci
121695b41eeSopenharmony_ci    /// Set bits starting from lowest for backslashes that were normalized to
122695b41eeSopenharmony_ci    /// forward slashes by CanonicalizePath. See |PathDecanonicalized|.
123695b41eeSopenharmony_ci    uint64_t slash_bits_ = 0;
124695b41eeSopenharmony_ci
125695b41eeSopenharmony_ci    /// Possible values of mtime_:
126695b41eeSopenharmony_ci    ///   -1: file hasn't been examined
127695b41eeSopenharmony_ci    ///   0:  we looked, and file doesn't exist
128695b41eeSopenharmony_ci    ///   >0: actual file's mtime, or the latest mtime of its dependencies if it doesn't exist
129695b41eeSopenharmony_ci    TimeStamp mtime_ = -1;
130695b41eeSopenharmony_ci
131695b41eeSopenharmony_ci    enum ExistenceStatus {
132695b41eeSopenharmony_ci        /// The file hasn't been examined.
133695b41eeSopenharmony_ci        ExistenceStatusUnknown,
134695b41eeSopenharmony_ci        /// The file doesn't exist. mtime_ will be the latest mtime of its dependencies.
135695b41eeSopenharmony_ci        ExistenceStatusMissing,
136695b41eeSopenharmony_ci        /// The path is an actual file. mtime_ will be the file's mtime.
137695b41eeSopenharmony_ci        ExistenceStatusExists
138695b41eeSopenharmony_ci    };
139695b41eeSopenharmony_ci    ExistenceStatus exists_ = ExistenceStatusUnknown;
140695b41eeSopenharmony_ci
141695b41eeSopenharmony_ci    /// Dirty is true when the underlying file is out-of-date.
142695b41eeSopenharmony_ci    /// But note that Edge::outputs_ready_ is also used in judging which
143695b41eeSopenharmony_ci    /// edges to build.
144695b41eeSopenharmony_ci    bool dirty_ = false;
145695b41eeSopenharmony_ci
146695b41eeSopenharmony_ci    /// Store whether dyndep information is expected from this node but
147695b41eeSopenharmony_ci    /// has not yet been loaded.
148695b41eeSopenharmony_ci    bool dyndep_pending_ = false;
149695b41eeSopenharmony_ci
150695b41eeSopenharmony_ci    /// Set to true when this node comes from a depfile, a dyndep file or the
151695b41eeSopenharmony_ci    /// deps log. If it does not have a producing edge, the build should not
152695b41eeSopenharmony_ci    /// abort if it is missing (as for regular source inputs). By default
153695b41eeSopenharmony_ci    /// all nodes have this flag set to true, since the deps and build logs
154695b41eeSopenharmony_ci    /// can be loaded before the manifest.
155695b41eeSopenharmony_ci    bool generated_by_dep_loader_ = true;
156695b41eeSopenharmony_ci
157695b41eeSopenharmony_ci    /// The Edge that produces this Node, or NULL when there is no
158695b41eeSopenharmony_ci    /// known edge to produce it.
159695b41eeSopenharmony_ci    Edge* in_edge_ = nullptr;
160695b41eeSopenharmony_ci
161695b41eeSopenharmony_ci    /// All Edges that use this Node as an input.
162695b41eeSopenharmony_ci    std::vector<Edge*> out_edges_;
163695b41eeSopenharmony_ci
164695b41eeSopenharmony_ci    /// All Edges that use this Node as a validation.
165695b41eeSopenharmony_ci    std::vector<Edge*> validation_out_edges_;
166695b41eeSopenharmony_ci
167695b41eeSopenharmony_ci    /// A dense integer id for the node, assigned and used by DepsLog.
168695b41eeSopenharmony_ci    int id_ = -1;
169695b41eeSopenharmony_ci};
170695b41eeSopenharmony_ci
171695b41eeSopenharmony_ci/// An edge in the dependency graph; links between Nodes using Rules.
172695b41eeSopenharmony_cistruct Edge {
173695b41eeSopenharmony_ci    enum VisitMark {
174695b41eeSopenharmony_ci        VisitNone,
175695b41eeSopenharmony_ci        VisitInStack,
176695b41eeSopenharmony_ci        VisitDone
177695b41eeSopenharmony_ci    };
178695b41eeSopenharmony_ci
179695b41eeSopenharmony_ci    Edge()
180695b41eeSopenharmony_ci            : rule_(NULL), pool_(NULL), dyndep_(NULL), env_(NULL), mark_(VisitNone),
181695b41eeSopenharmony_ci                id_(0), outputs_ready_(false), deps_loaded_(false),
182695b41eeSopenharmony_ci                deps_missing_(false), generated_by_dep_loader_(false),
183695b41eeSopenharmony_ci                command_start_time_(0), implicit_deps_(0), order_only_deps_(0),
184695b41eeSopenharmony_ci                implicit_outs_(0) {}
185695b41eeSopenharmony_ci
186695b41eeSopenharmony_ci    /// Return true if all inputs' in-edges are ready.
187695b41eeSopenharmony_ci    bool AllInputsReady() const;
188695b41eeSopenharmony_ci
189695b41eeSopenharmony_ci    /// Expand all variables in a command and return it as a string.
190695b41eeSopenharmony_ci    /// If incl_rsp_file is enabled, the string will also contain the
191695b41eeSopenharmony_ci    /// full contents of a response file (if applicable)
192695b41eeSopenharmony_ci    std::string EvaluateCommand(bool incl_rsp_file = false) const;
193695b41eeSopenharmony_ci
194695b41eeSopenharmony_ci    /// Returns the shell-escaped value of |key|.
195695b41eeSopenharmony_ci    std::string GetBinding(const std::string& key) const;
196695b41eeSopenharmony_ci    bool GetBindingBool(const std::string& key) const;
197695b41eeSopenharmony_ci
198695b41eeSopenharmony_ci    /// Like GetBinding("depfile"), but without shell escaping.
199695b41eeSopenharmony_ci    std::string GetUnescapedDepfile() const;
200695b41eeSopenharmony_ci    /// Like GetBinding("dyndep"), but without shell escaping.
201695b41eeSopenharmony_ci    std::string GetUnescapedDyndep() const;
202695b41eeSopenharmony_ci    /// Like GetBinding("rspfile"), but without shell escaping.
203695b41eeSopenharmony_ci    std::string GetUnescapedRspfile() const;
204695b41eeSopenharmony_ci
205695b41eeSopenharmony_ci    void Dump(const char* prefix="") const;
206695b41eeSopenharmony_ci
207695b41eeSopenharmony_ci    // Append all edge explicit inputs to |*out|. Possibly with shell escaping.
208695b41eeSopenharmony_ci    void CollectInputs(bool shell_escape, std::vector<std::string>* out) const;
209695b41eeSopenharmony_ci
210695b41eeSopenharmony_ci    const Rule* rule_ = nullptr;
211695b41eeSopenharmony_ci    Pool* pool_ = nullptr;
212695b41eeSopenharmony_ci    std::vector<Node*> inputs_;
213695b41eeSopenharmony_ci    std::vector<Node*> outputs_;
214695b41eeSopenharmony_ci    std::vector<Node*> validations_;
215695b41eeSopenharmony_ci    Node* dyndep_ = nullptr;
216695b41eeSopenharmony_ci    BindingEnv* env_ = nullptr;
217695b41eeSopenharmony_ci    VisitMark mark_ = VisitNone;
218695b41eeSopenharmony_ci    size_t id_ = 0;
219695b41eeSopenharmony_ci    bool outputs_ready_ = false;
220695b41eeSopenharmony_ci    bool deps_loaded_ = false;
221695b41eeSopenharmony_ci    bool deps_missing_ = false;
222695b41eeSopenharmony_ci    bool generated_by_dep_loader_ = false;
223695b41eeSopenharmony_ci    TimeStamp command_start_time_ = 0;
224695b41eeSopenharmony_ci
225695b41eeSopenharmony_ci    const Rule& rule() const { return *rule_; }
226695b41eeSopenharmony_ci    Pool* pool() const { return pool_; }
227695b41eeSopenharmony_ci    int weight() const { return 1; }
228695b41eeSopenharmony_ci    bool outputs_ready() const { return outputs_ready_; }
229695b41eeSopenharmony_ci
230695b41eeSopenharmony_ci    // There are three types of inputs.
231695b41eeSopenharmony_ci    // 1) explicit deps, which show up as $in on the command line;
232695b41eeSopenharmony_ci    // 2) implicit deps, which the target depends on implicitly (e.g. C headers),
233695b41eeSopenharmony_ci    //                   and changes in them cause the target to rebuild;
234695b41eeSopenharmony_ci    // 3) order-only deps, which are needed before the target builds but which
235695b41eeSopenharmony_ci    //                     don't cause the target to rebuild.
236695b41eeSopenharmony_ci    // These are stored in inputs_ in that order, and we keep counts of
237695b41eeSopenharmony_ci    // #2 and #3 when we need to access the various subsets.
238695b41eeSopenharmony_ci    int implicit_deps_ = 0;
239695b41eeSopenharmony_ci    int order_only_deps_ = 0;
240695b41eeSopenharmony_ci    bool is_implicit(size_t index) {
241695b41eeSopenharmony_ci        return index >= inputs_.size() - order_only_deps_ - implicit_deps_ &&
242695b41eeSopenharmony_ci                !is_order_only(index);
243695b41eeSopenharmony_ci    }
244695b41eeSopenharmony_ci    bool is_order_only(size_t index) {
245695b41eeSopenharmony_ci        return index >= inputs_.size() - order_only_deps_;
246695b41eeSopenharmony_ci    }
247695b41eeSopenharmony_ci
248695b41eeSopenharmony_ci    // There are two types of outputs.
249695b41eeSopenharmony_ci    // 1) explicit outs, which show up as $out on the command line;
250695b41eeSopenharmony_ci    // 2) implicit outs, which the target generates but are not part of $out.
251695b41eeSopenharmony_ci    // These are stored in outputs_ in that order, and we keep a count of
252695b41eeSopenharmony_ci    // #2 to use when we need to access the various subsets.
253695b41eeSopenharmony_ci    int implicit_outs_ = 0;
254695b41eeSopenharmony_ci    bool is_implicit_out(size_t index) const {
255695b41eeSopenharmony_ci        return index >= outputs_.size() - implicit_outs_;
256695b41eeSopenharmony_ci    }
257695b41eeSopenharmony_ci
258695b41eeSopenharmony_ci    bool is_phony() const;
259695b41eeSopenharmony_ci    bool use_console() const;
260695b41eeSopenharmony_ci    bool maybe_phonycycle_diagnostic() const;
261695b41eeSopenharmony_ci
262695b41eeSopenharmony_ci    // Historical info: how long did this edge take last time,
263695b41eeSopenharmony_ci    // as per .ninja_log, if known? Defaults to -1 if unknown.
264695b41eeSopenharmony_ci    int64_t prev_elapsed_time_millis = -1;
265695b41eeSopenharmony_ci};
266695b41eeSopenharmony_ci
267695b41eeSopenharmony_cistruct EdgeCmp {
268695b41eeSopenharmony_ci    bool operator()(const Edge* a, const Edge* b) const {
269695b41eeSopenharmony_ci        return a->id_ < b->id_;
270695b41eeSopenharmony_ci    }
271695b41eeSopenharmony_ci};
272695b41eeSopenharmony_ci
273695b41eeSopenharmony_citypedef std::set<Edge*, EdgeCmp> EdgeSet;
274695b41eeSopenharmony_ci
275695b41eeSopenharmony_ci/// ImplicitDepLoader loads implicit dependencies, as referenced via the
276695b41eeSopenharmony_ci/// "depfile" attribute in build files.
277695b41eeSopenharmony_cistruct ImplicitDepLoader {
278695b41eeSopenharmony_ci    ImplicitDepLoader(State* state, DepsLog* deps_log,
279695b41eeSopenharmony_ci                                        DiskInterface* disk_interface,
280695b41eeSopenharmony_ci                                        DepfileParserOptions const* depfile_parser_options)
281695b41eeSopenharmony_ci            : state_(state), disk_interface_(disk_interface), deps_log_(deps_log),
282695b41eeSopenharmony_ci                depfile_parser_options_(depfile_parser_options) {}
283695b41eeSopenharmony_ci
284695b41eeSopenharmony_ci    /// Load implicit dependencies for \a edge.
285695b41eeSopenharmony_ci    /// @return false on error (without filling \a err if info is just missing
286695b41eeSopenharmony_ci    //                          or out of date).
287695b41eeSopenharmony_ci    bool LoadDeps(Edge* edge, std::string* err);
288695b41eeSopenharmony_ci
289695b41eeSopenharmony_ci    DepsLog* deps_log() const {
290695b41eeSopenharmony_ci        return deps_log_;
291695b41eeSopenharmony_ci    }
292695b41eeSopenharmony_ci
293695b41eeSopenharmony_ci  protected:
294695b41eeSopenharmony_ci    /// Process loaded implicit dependencies for \a edge and update the graph
295695b41eeSopenharmony_ci    /// @return false on error (without filling \a err if info is just missing)
296695b41eeSopenharmony_ci    virtual bool ProcessDepfileDeps(Edge* edge,
297695b41eeSopenharmony_ci                                                                    std::vector<StringPiece>* depfile_ins,
298695b41eeSopenharmony_ci                                                                    std::string* err);
299695b41eeSopenharmony_ci
300695b41eeSopenharmony_ci    /// Load implicit dependencies for \a edge from a depfile attribute.
301695b41eeSopenharmony_ci    /// @return false on error (without filling \a err if info is just missing).
302695b41eeSopenharmony_ci    bool LoadDepFile(Edge* edge, const std::string& path, std::string* err);
303695b41eeSopenharmony_ci
304695b41eeSopenharmony_ci    /// Load implicit dependencies for \a edge from the DepsLog.
305695b41eeSopenharmony_ci    /// @return false on error (without filling \a err if info is just missing).
306695b41eeSopenharmony_ci    bool LoadDepsFromLog(Edge* edge, std::string* err);
307695b41eeSopenharmony_ci
308695b41eeSopenharmony_ci    /// Preallocate \a count spaces in the input array on \a edge, returning
309695b41eeSopenharmony_ci    /// an iterator pointing at the first new space.
310695b41eeSopenharmony_ci    std::vector<Node*>::iterator PreallocateSpace(Edge* edge, int count);
311695b41eeSopenharmony_ci
312695b41eeSopenharmony_ci    State* state_;
313695b41eeSopenharmony_ci    DiskInterface* disk_interface_;
314695b41eeSopenharmony_ci    DepsLog* deps_log_;
315695b41eeSopenharmony_ci    DepfileParserOptions const* depfile_parser_options_;
316695b41eeSopenharmony_ci};
317695b41eeSopenharmony_ci
318695b41eeSopenharmony_ci
319695b41eeSopenharmony_ci/// DependencyScan manages the process of scanning the files in a graph
320695b41eeSopenharmony_ci/// and updating the dirty/outputs_ready state of all the nodes and edges.
321695b41eeSopenharmony_cistruct DependencyScan {
322695b41eeSopenharmony_ci    DependencyScan(State* state, BuildLog* build_log, DepsLog* deps_log,
323695b41eeSopenharmony_ci                                  DiskInterface* disk_interface,
324695b41eeSopenharmony_ci                                  DepfileParserOptions const* depfile_parser_options)
325695b41eeSopenharmony_ci            : build_log_(build_log),
326695b41eeSopenharmony_ci                disk_interface_(disk_interface),
327695b41eeSopenharmony_ci                dep_loader_(state, deps_log, disk_interface, depfile_parser_options),
328695b41eeSopenharmony_ci                dyndep_loader_(state, disk_interface) {}
329695b41eeSopenharmony_ci
330695b41eeSopenharmony_ci    /// Update the |dirty_| state of the given nodes by transitively inspecting
331695b41eeSopenharmony_ci    /// their input edges.
332695b41eeSopenharmony_ci    /// Examine inputs, outputs, and command lines to judge whether an edge
333695b41eeSopenharmony_ci    /// needs to be re-run, and update outputs_ready_ and each outputs' |dirty_|
334695b41eeSopenharmony_ci    /// state accordingly.
335695b41eeSopenharmony_ci    /// Appends any validation nodes found to the nodes parameter.
336695b41eeSopenharmony_ci    /// Returns false on failure.
337695b41eeSopenharmony_ci    bool RecomputeDirty(Node* node, std::vector<Node*>* validation_nodes, std::string* err);
338695b41eeSopenharmony_ci
339695b41eeSopenharmony_ci    /// Recompute whether any output of the edge is dirty, if so sets |*dirty|.
340695b41eeSopenharmony_ci    /// Returns false on failure.
341695b41eeSopenharmony_ci    bool RecomputeOutputsDirty(Edge* edge, Node* most_recent_input,
342695b41eeSopenharmony_ci                                                          bool* dirty, std::string* err);
343695b41eeSopenharmony_ci
344695b41eeSopenharmony_ci    BuildLog* build_log() const {
345695b41eeSopenharmony_ci        return build_log_;
346695b41eeSopenharmony_ci    }
347695b41eeSopenharmony_ci    void set_build_log(BuildLog* log) {
348695b41eeSopenharmony_ci        build_log_ = log;
349695b41eeSopenharmony_ci    }
350695b41eeSopenharmony_ci
351695b41eeSopenharmony_ci    DepsLog* deps_log() const {
352695b41eeSopenharmony_ci        return dep_loader_.deps_log();
353695b41eeSopenharmony_ci    }
354695b41eeSopenharmony_ci
355695b41eeSopenharmony_ci    /// Load a dyndep file from the given node's path and update the
356695b41eeSopenharmony_ci    /// build graph with the new information.  One overload accepts
357695b41eeSopenharmony_ci    /// a caller-owned 'DyndepFile' object in which to store the
358695b41eeSopenharmony_ci    /// information loaded from the dyndep file.
359695b41eeSopenharmony_ci    bool LoadDyndeps(Node* node, std::string* err) const;
360695b41eeSopenharmony_ci    bool LoadDyndeps(Node* node, DyndepFile* ddf, std::string* err) const;
361695b41eeSopenharmony_ci
362695b41eeSopenharmony_ci  private:
363695b41eeSopenharmony_ci    bool RecomputeNodeDirty(Node* node, std::vector<Node*>* stack,
364695b41eeSopenharmony_ci                                                    std::vector<Node*>* validation_nodes, std::string* err);
365695b41eeSopenharmony_ci    bool VerifyDAG(Node* node, std::vector<Node*>* stack, std::string* err);
366695b41eeSopenharmony_ci
367695b41eeSopenharmony_ci    /// Recompute whether a given single output should be marked dirty.
368695b41eeSopenharmony_ci    /// Returns true if so.
369695b41eeSopenharmony_ci    bool RecomputeOutputDirty(const Edge* edge, const Node* most_recent_input,
370695b41eeSopenharmony_ci                                                        const std::string& command, Node* output);
371695b41eeSopenharmony_ci
372695b41eeSopenharmony_ci    BuildLog* build_log_;
373695b41eeSopenharmony_ci    DiskInterface* disk_interface_;
374695b41eeSopenharmony_ci    ImplicitDepLoader dep_loader_;
375695b41eeSopenharmony_ci    DyndepLoader dyndep_loader_;
376695b41eeSopenharmony_ci};
377695b41eeSopenharmony_ci
378695b41eeSopenharmony_ci#endif  // NINJA_GRAPH_H_
379