-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow 'ninja -t compdb' accept one target #1546
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unordered_set> | ||
|
||
#ifdef _WIN32 | ||
#include "getopt.h" | ||
|
@@ -699,6 +700,38 @@ string EvaluateCommandWithRspfile(Edge* edge, EvaluateCommandMode mode) { | |
return command; | ||
} | ||
|
||
bool GetAllDependentEdges(Node* node, std::vector<Edge*>* depend_edges, | ||
std::unordered_set<Node*>* visited_nodes=NULL, | ||
std::unordered_set<Edge*>* visited_edges=NULL) { | ||
if (visited_nodes == NULL || visited_edges == NULL) { | ||
std::unordered_set<Node*> visited_nodes_; | ||
std::unordered_set<Edge*> visited_edges_; | ||
return GetAllDependentEdges(node, depend_edges, &visited_nodes_, &visited_edges_); | ||
} | ||
if (node == NULL || depend_edges == NULL) { | ||
Error("Internal error"); | ||
return false; | ||
} | ||
if (visited_nodes->count(node)) { | ||
return true; | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for |
||
visited_nodes->insert(node); | ||
} | ||
Edge* edge = node->in_edge(); | ||
// Leaf node | ||
if (!edge || visited_edges->count(edge)) { | ||
return true; | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
visited_edges->insert(edge); | ||
depend_edges->push_back(edge); | ||
} | ||
for (Node* input_node : edge->inputs_) { | ||
if (!GetAllDependentEdges(input_node, depend_edges, visited_nodes, visited_edges)) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, | ||
char* argv[]) { | ||
// The compdb tool uses getopt, and expects argv[0] to contain the name of | ||
|
@@ -710,26 +743,51 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, | |
|
||
optind = 1; | ||
int opt; | ||
while ((opt = getopt(argc, argv, const_cast<char*>("hx"))) != -1) { | ||
string err; | ||
Node* user_given_target = NULL; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please create a scope in for See http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-introduce |
||
while ((opt = getopt(argc, argv, const_cast<char*>("hxa"))) != -1) { | ||
switch(opt) { | ||
case 'x': | ||
eval_mode = ECM_EXPAND_RSPFILE; | ||
break; | ||
|
||
case 'a': | ||
if (argc < 3) { | ||
Error("Expecting one target name"); | ||
return 1; | ||
} | ||
user_given_target = CollectTarget(argv[optind], &err); | ||
if (!user_given_target) { | ||
Error("%s: %s", argv[optind], err.c_str()); | ||
return 1; | ||
} | ||
break; | ||
|
||
case 'h': | ||
default: | ||
printf( | ||
"usage: ninja -t compdb [options] [rules]\n" | ||
"usage: ninja -t compdb [options] [target] [rules]\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't |
||
"\n" | ||
"options:\n" | ||
" -x expand @rspfile style response file invocations\n" | ||
" -a generate compilation database for given target\n" | ||
); | ||
return 1; | ||
} | ||
} | ||
argv += optind; | ||
argc -= optind; | ||
|
||
std::vector<Edge*> user_interested_edges; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also move this variable into the |
||
std::vector<Edge*>* edges_to_process = NULL; | ||
if (user_given_target) { | ||
if (!GetAllDependentEdges(user_given_target, &user_interested_edges)) | ||
return 1; | ||
edges_to_process = &user_interested_edges; | ||
} else { | ||
edges_to_process = &(state_.edges_); | ||
} | ||
|
||
bool first = true; | ||
vector<char> cwd; | ||
|
||
|
@@ -743,8 +801,8 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, | |
} | ||
|
||
putchar('['); | ||
for (vector<Edge*>::iterator e = state_.edges_.begin(); | ||
e != state_.edges_.end(); ++e) { | ||
for (vector<Edge*>::iterator e = edges_to_process->begin(); | ||
e != edges_to_process->end(); ++e) { | ||
if ((*e)->inputs_.empty()) | ||
continue; | ||
for (int i = 0; i != argc; ++i) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use
assert
for this instead.