33 NodeStoringImplicitDepLoader(
36 Explanations* explanations, std::vector<Node*>* dep_nodes_output)
38 depfile_parser_options, explanations),
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,
nullptr,
104 dep_loader.LoadDeps(edge, &err);
105 if (!depfile_deps.empty())
107 static_cast<int>(depfile_deps.size()));
112 int dep_nodes_count) {
114 std::set<Edge*> deplog_edges;
115 for (
int i = 0; i < dep_nodes_count; ++i) {
116 Node* deplog_node = dep_nodes[i];
123 if (deplog_node->
path() ==
"build.ninja")
127 deplog_edges.insert(deplog_edge);
130 std::vector<Edge*> missing_deps;
131 for (std::set<Edge*>::iterator de = deplog_edges.begin();
132 de != deplog_edges.end(); ++de) {
134 missing_deps.push_back(*de);
138 if (!missing_deps.empty()) {
139 std::set<std::string> missing_deps_rule_names;
140 for (std::vector<Edge*>::iterator ne = missing_deps.begin();
141 ne != missing_deps.end(); ++ne) {
142 for (
int i = 0; i < dep_nodes_count; ++i) {
143 if (dep_nodes[i]->in_edge() == *ne) {
146 missing_deps_rule_names.insert((*ne)->rule().name());
157 std::cout <<
"Processed " <<
seen_.size() <<
" nodes.\n";
160 <<
" missing dependency paths.\n";
162 <<
" targets had depfile dependencies on "
165 <<
" without a non-depfile dep path to the generator.\n";
166 std::cout <<
"There might be build flakiness if any of the targets listed "
167 "above are built alone, or not late enough, in a clean output "
170 std::cout <<
"No missing dependencies on generated files found.\n";
177 InnerAdjacencyMap::iterator inner_it = it->second.find(to);
178 if (inner_it != it->second.end()) {
179 return inner_it->second;
185 for (
size_t i = 0; i < to->
inputs_.size(); ++i) {
192 it->second.insert(std::make_pair(to, found));
void OnMissingDep(Node *node, const std::string &path, const Rule &generator)
virtual ~MissingDependencyScannerDelegate()
virtual void OnMissingDep(Node *node, const std::string &path, const Rule &generator)=0
As build commands run they can output extra dependency information (e.g.
Deps * GetDeps(Node *node)
Interface for accessing the disk.
An edge in the dependency graph; links between Nodes using Rules.
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
std::vector< Node * > inputs_
A class used to record a list of explanation strings associated with a given 'item' pointer.
ImplicitDepLoader loads implicit dependencies, as referenced via the "depfile" attribute in build fil...
virtual bool ProcessDepfileDeps(Edge *edge, std::vector< StringPiece > *depfile_ins, std::string *err)
Process loaded implicit dependencies for edge and update the graph.
MissingDependencyScanner(MissingDependencyScannerDelegate *delegate, DepsLog *deps_log, State *state, DiskInterface *disk_interface)
std::set< const Rule * > generator_rules_
bool PathExistsBetween(Edge *from, Edge *to)
MissingDependencyScannerDelegate * delegate_
std::set< Node * > generated_nodes_
void ProcessNode(Node *node)
std::unordered_map< Edge *, bool > InnerAdjacencyMap
void ProcessNodeDeps(Node *node, Node **dep_nodes, int dep_nodes_count)
DiskInterface * disk_interface_
std::set< Node * > nodes_missing_deps_
AdjacencyMap adjacency_map_
int missing_dep_path_count_
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
const std::string & path() const
An invocable build command and associated metadata (description, etc.).
const std::string & name() const
Global state (file status) for a single run.
void CanonicalizePath(string *path, uint64_t *slash_bits)
unsigned long long uint64_t