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