Index: tools/gn/command_desc.cc |
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc |
index 16aee40669e1f5dd780409eeb60ed5215ef923d4..e24f0e44f02617548f14aece8db2d5c848024249 100644 |
--- a/tools/gn/command_desc.cc |
+++ b/tools/gn/command_desc.cc |
@@ -58,9 +58,13 @@ void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { |
RecursiveCollectDeps(datadeps[i].ptr, result); |
} |
-// Prints dependencies of the given target (not the target itself). |
+// Prints dependencies of the given target (not the target itself). If the |
+// set is non-null, new targets encountered will be added to the set, and if |
+// a dependency is in the set already, it will not be recused into. When the |
+// set is null, all dependencies will be printed. |
void RecursivePrintDeps(const Target* target, |
const Label& default_toolchain, |
+ std::set<const Target*>* seen_targets, |
int indent_level) { |
LabelTargetVector sorted_deps = target->deps(); |
const LabelTargetVector& datadeps = target->datadeps(); |
@@ -70,6 +74,8 @@ void RecursivePrintDeps(const Target* target, |
std::string indent(indent_level * 2, ' '); |
for (size_t i = 0; i < sorted_deps.size(); i++) { |
+ const Target* cur_dep = sorted_deps[i].ptr; |
+ |
// Don't print groups. Groups are flattened such that the deps of the |
// group are added directly to the target that depended on the group. |
// Printing and recursing into groups here will cause such targets to be |
@@ -78,12 +84,31 @@ void RecursivePrintDeps(const Target* target, |
// It would be much more intuitive to do the opposite and not display the |
// deps that were copied from the group to the target and instead display |
// the group, but the source of those dependencies is not tracked. |
- if (sorted_deps[i].ptr->output_type() == Target::GROUP) |
+ if (cur_dep->output_type() == Target::GROUP) |
continue; |
OutputString(indent + |
- sorted_deps[i].label.GetUserVisibleName(default_toolchain) + "\n"); |
- RecursivePrintDeps(sorted_deps[i].ptr, default_toolchain, indent_level + 1); |
+ cur_dep->label().GetUserVisibleName(default_toolchain)); |
+ bool print_children = true; |
+ if (seen_targets) { |
+ if (seen_targets->find(cur_dep) == seen_targets->end()) { |
+ // New target, mark it visited. |
+ seen_targets->insert(cur_dep); |
+ } else { |
+ // Already seen. |
+ print_children = false; |
+ // Only print "..." if something is actually elided, which means that |
+ // the current target has children. |
+ if (!cur_dep->deps().empty() || !cur_dep->datadeps().empty()) |
+ OutputString("..."); |
+ } |
+ } |
+ |
+ OutputString("\n"); |
+ if (print_children) { |
+ RecursivePrintDeps(cur_dep, default_toolchain, seen_targets, |
+ indent_level + 1); |
+ } |
} |
} |
@@ -95,7 +120,15 @@ void PrintDeps(const Target* target, bool display_header) { |
if (cmdline->HasSwitch("tree")) { |
if (display_header) |
OutputString("\nDependency tree:\n"); |
- RecursivePrintDeps(target, toolchain_label, 1); |
+ |
+ if (cmdline->HasSwitch("all")) { |
+ // Show all tree deps with no eliding. |
+ RecursivePrintDeps(target, toolchain_label, NULL, 1); |
+ } else { |
+ // Don't recurse into duplicates. |
+ std::set<const Target*> seen_targets; |
+ RecursivePrintDeps(target, toolchain_label, &seen_targets, 1); |
+ } |
return; |
} |
@@ -112,8 +145,9 @@ void PrintDeps(const Target* target, bool display_header) { |
deps.push_back(*i); |
} else { |
if (display_header) { |
- OutputString("\nDirect dependencies " |
- "(try also \"--all\" and \"--tree\"):\n"); |
+ OutputString( |
+ "\nDirect dependencies " |
+ "(try also \"--all\", \"--tree\", or even \"--all --tree\"):\n"); |
} |
const LabelTargetVector& target_deps = target->deps(); |
@@ -420,8 +454,10 @@ const char kDesc_Help[] = |
" deps [--all | --tree]\n" |
" Show immediate (or, when \"--all\" or \"--tree\" is specified,\n" |
" recursive) dependencies of the given target. \"--tree\" shows them\n" |
- " in a tree format. Otherwise, they will be sorted alphabetically.\n" |
- " Both \"deps\" and \"datadeps\" will be included.\n" |
+ " in a tree format with duplicates elided (noted by \"...\").\n" |
+ " \"--all\" shows them sorted alphabetically. Using both flags will\n" |
+ " print a tree with no omissions. Both \"deps\" and \"datadeps\"\n" |
+ " will be included.\n" |
"\n" |
" direct_dependent_configs\n" |
" all_dependent_configs\n" |