33 NodeStoringImplicitDepLoader(
36 std::vector<Node*>* dep_nodes_output)
38 depfile_parser_options),
39 dep_nodes_output_(dep_nodes_output) {}
43 std::vector<StringPiece>* depfile_ins,
47 std::vector<Node*>* dep_nodes_output_;
50 bool NodeStoringImplicitDepLoader::ProcessDepfileDeps(
51 Edge* edge, std::vector<StringPiece>* depfile_ins, std::string* err) {
52 for (std::vector<StringPiece>::iterator i = depfile_ins->begin();
53 i != depfile_ins->end(); ++i) {
56 Node* node = state_->GetNode(*i, slash_bits);
57 dep_nodes_output_->push_back(node);
67 const Rule& generator) {
68 std::cout <<
"Missing dep: " << node->
path() <<
" uses " << path
69 <<
" (generated by " << generator.
name() <<
")\n";
75 : delegate_(delegate), deps_log_(deps_log), state_(state),
76 disk_interface_(disk_interface), missing_dep_path_count_(0) {}
84 if (!
seen_.insert(node).second)
87 for (std::vector<Node*>::iterator in = edge->
inputs_.begin();
88 in != edge->
inputs_.end(); ++in) {
92 std::string deps_type = edge->
GetBinding(
"deps");
93 if (!deps_type.empty()) {
99 std::vector<Node*> depfile_deps;
101 &parser_opts, &depfile_deps);
103 dep_loader.LoadDeps(edge, &err);
104 if (!depfile_deps.empty())
110 int dep_nodes_count) {
112 std::set<Edge*> deplog_edges;
113 for (
int i = 0; i < dep_nodes_count; ++i) {
114 Node* deplog_node = dep_nodes[i];
121 if (deplog_node->
path() ==
"build.ninja")
125 deplog_edges.insert(deplog_edge);
128 std::vector<Edge*> missing_deps;
129 for (std::set<Edge*>::iterator de = deplog_edges.begin();
130 de != deplog_edges.end(); ++de) {
132 missing_deps.push_back(*de);
136 if (!missing_deps.empty()) {
137 std::set<std::string> missing_deps_rule_names;
138 for (std::vector<Edge*>::iterator ne = missing_deps.begin();
139 ne != missing_deps.end(); ++ne) {
140 for (
int i = 0; i < dep_nodes_count; ++i) {
141 if (dep_nodes[i]->in_edge() == *ne) {
144 missing_deps_rule_names.insert((*ne)->rule().name());
155 std::cout <<
"Processed " <<
seen_.size() <<
" nodes.\n";
158 <<
" missing dependency paths.\n";
160 <<
" targets had depfile dependencies on " 163 <<
" without a non-depfile dep path to the generator.\n";
164 std::cout <<
"There might be build flakiness if any of the targets listed " 165 "above are built alone, or not late enough, in a clean output " 168 std::cout <<
"No missing dependencies on generated files found.\n";
175 InnerAdjacencyMap::iterator inner_it = it->second.find(to);
176 if (inner_it != it->second.end()) {
177 return inner_it->second;
183 for (
size_t i = 0; i < to->
inputs_.size(); ++i) {
190 it->second.insert(std::make_pair(to, found));
void OnMissingDep(Node *node, const std::string &path, const Rule &generator)
void ProcessNodeDeps(Node *node, Node **dep_nodes, int dep_nodes_count)
virtual void OnMissingDep(Node *node, const std::string &path, const Rule &generator)=0
std::set< Node * > nodes_missing_deps_
const std::string & name() const
MissingDependencyScanner(MissingDependencyScannerDelegate *delegate, DepsLog *deps_log, State *state, DiskInterface *disk_interface)
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
virtual bool ProcessDepfileDeps(Edge *edge, std::vector< StringPiece > *depfile_ins, std::string *err)
Process loaded implicit dependencies for edge and update the graph.
Interface for accessing the disk.
An edge in the dependency graph; links between Nodes using Rules.
virtual ~MissingDependencyScannerDelegate()
const std::string & path() const
As build commands run they can output extra dependency information (e.g.
AdjacencyMap adjacency_map_
void ProcessNode(Node *node)
std::set< Node * > generated_nodes_
An invocable build command and associated metadata (description, etc.).
Deps * GetDeps(Node *node)
std::map< Edge *, bool > InnerAdjacencyMap
std::vector< Node * > inputs_
std::set< const Rule * > generator_rules_
DiskInterface * disk_interface_
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
ImplicitDepLoader loads implicit dependencies, as referenced via the "depfile" attribute in build fil...
void CanonicalizePath(string *path, uint64_t *slash_bits)
Global state (file status) for a single run.
unsigned long long uint64_t
bool PathExistsBetween(Edge *from, Edge *to)
int missing_dep_path_count_
MissingDependencyScannerDelegate * delegate_