OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <set> | 6 #include <set> |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "tools/gn/commands.h" | 10 #include "tools/gn/commands.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { | 51 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { |
52 const LabelTargetVector& deps = target->deps(); | 52 const LabelTargetVector& deps = target->deps(); |
53 for (size_t i = 0; i < deps.size(); i++) | 53 for (size_t i = 0; i < deps.size(); i++) |
54 RecursiveCollectDeps(deps[i].ptr, result); | 54 RecursiveCollectDeps(deps[i].ptr, result); |
55 | 55 |
56 const LabelTargetVector& datadeps = target->datadeps(); | 56 const LabelTargetVector& datadeps = target->datadeps(); |
57 for (size_t i = 0; i < datadeps.size(); i++) | 57 for (size_t i = 0; i < datadeps.size(); i++) |
58 RecursiveCollectDeps(datadeps[i].ptr, result); | 58 RecursiveCollectDeps(datadeps[i].ptr, result); |
59 } | 59 } |
60 | 60 |
61 // Prints dependencies of the given target (not the target itself). | 61 // Prints dependencies of the given target (not the target itself). If the |
| 62 // set is non-null, new targets encountered will be added to the set, and if |
| 63 // a dependency is in the set already, it will not be recused into. When the |
| 64 // set is null, all dependencies will be printed. |
62 void RecursivePrintDeps(const Target* target, | 65 void RecursivePrintDeps(const Target* target, |
63 const Label& default_toolchain, | 66 const Label& default_toolchain, |
| 67 std::set<const Target*>* seen_targets, |
64 int indent_level) { | 68 int indent_level) { |
65 LabelTargetVector sorted_deps = target->deps(); | 69 LabelTargetVector sorted_deps = target->deps(); |
66 const LabelTargetVector& datadeps = target->datadeps(); | 70 const LabelTargetVector& datadeps = target->datadeps(); |
67 sorted_deps.insert(sorted_deps.end(), datadeps.begin(), datadeps.end()); | 71 sorted_deps.insert(sorted_deps.end(), datadeps.begin(), datadeps.end()); |
68 std::sort(sorted_deps.begin(), sorted_deps.end(), | 72 std::sort(sorted_deps.begin(), sorted_deps.end(), |
69 LabelPtrLabelLess<Target>()); | 73 LabelPtrLabelLess<Target>()); |
70 | 74 |
71 std::string indent(indent_level * 2, ' '); | 75 std::string indent(indent_level * 2, ' '); |
72 for (size_t i = 0; i < sorted_deps.size(); i++) { | 76 for (size_t i = 0; i < sorted_deps.size(); i++) { |
| 77 const Target* cur_dep = sorted_deps[i].ptr; |
| 78 |
73 // Don't print groups. Groups are flattened such that the deps of the | 79 // Don't print groups. Groups are flattened such that the deps of the |
74 // group are added directly to the target that depended on the group. | 80 // group are added directly to the target that depended on the group. |
75 // Printing and recursing into groups here will cause such targets to be | 81 // Printing and recursing into groups here will cause such targets to be |
76 // duplicated. | 82 // duplicated. |
77 // | 83 // |
78 // It would be much more intuitive to do the opposite and not display the | 84 // It would be much more intuitive to do the opposite and not display the |
79 // deps that were copied from the group to the target and instead display | 85 // deps that were copied from the group to the target and instead display |
80 // the group, but the source of those dependencies is not tracked. | 86 // the group, but the source of those dependencies is not tracked. |
81 if (sorted_deps[i].ptr->output_type() == Target::GROUP) | 87 if (cur_dep->output_type() == Target::GROUP) |
82 continue; | 88 continue; |
83 | 89 |
84 OutputString(indent + | 90 OutputString(indent + |
85 sorted_deps[i].label.GetUserVisibleName(default_toolchain) + "\n"); | 91 cur_dep->label().GetUserVisibleName(default_toolchain)); |
86 RecursivePrintDeps(sorted_deps[i].ptr, default_toolchain, indent_level + 1); | 92 bool print_children = true; |
| 93 if (seen_targets) { |
| 94 if (seen_targets->find(cur_dep) == seen_targets->end()) { |
| 95 // New target, mark it visited. |
| 96 seen_targets->insert(cur_dep); |
| 97 } else { |
| 98 // Already seen. |
| 99 print_children = false; |
| 100 // Only print "..." if something is actually elided, which means that |
| 101 // the current target has children. |
| 102 if (!cur_dep->deps().empty() || !cur_dep->datadeps().empty()) |
| 103 OutputString("..."); |
| 104 } |
| 105 } |
| 106 |
| 107 OutputString("\n"); |
| 108 if (print_children) { |
| 109 RecursivePrintDeps(cur_dep, default_toolchain, seen_targets, |
| 110 indent_level + 1); |
| 111 } |
87 } | 112 } |
88 } | 113 } |
89 | 114 |
90 void PrintDeps(const Target* target, bool display_header) { | 115 void PrintDeps(const Target* target, bool display_header) { |
91 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 116 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
92 Label toolchain_label = target->label().GetToolchainLabel(); | 117 Label toolchain_label = target->label().GetToolchainLabel(); |
93 | 118 |
94 // Tree mode is separate. | 119 // Tree mode is separate. |
95 if (cmdline->HasSwitch("tree")) { | 120 if (cmdline->HasSwitch("tree")) { |
96 if (display_header) | 121 if (display_header) |
97 OutputString("\nDependency tree:\n"); | 122 OutputString("\nDependency tree:\n"); |
98 RecursivePrintDeps(target, toolchain_label, 1); | 123 |
| 124 if (cmdline->HasSwitch("all")) { |
| 125 // Show all tree deps with no eliding. |
| 126 RecursivePrintDeps(target, toolchain_label, NULL, 1); |
| 127 } else { |
| 128 // Don't recurse into duplicates. |
| 129 std::set<const Target*> seen_targets; |
| 130 RecursivePrintDeps(target, toolchain_label, &seen_targets, 1); |
| 131 } |
99 return; | 132 return; |
100 } | 133 } |
101 | 134 |
102 // Collect the deps to display. | 135 // Collect the deps to display. |
103 std::vector<Label> deps; | 136 std::vector<Label> deps; |
104 if (cmdline->HasSwitch("all")) { | 137 if (cmdline->HasSwitch("all")) { |
105 if (display_header) | 138 if (display_header) |
106 OutputString("\nAll recursive dependencies:\n"); | 139 OutputString("\nAll recursive dependencies:\n"); |
107 | 140 |
108 std::set<Label> all_deps; | 141 std::set<Label> all_deps; |
109 RecursiveCollectChildDeps(target, &all_deps); | 142 RecursiveCollectChildDeps(target, &all_deps); |
110 for (std::set<Label>::iterator i = all_deps.begin(); | 143 for (std::set<Label>::iterator i = all_deps.begin(); |
111 i != all_deps.end(); ++i) | 144 i != all_deps.end(); ++i) |
112 deps.push_back(*i); | 145 deps.push_back(*i); |
113 } else { | 146 } else { |
114 if (display_header) { | 147 if (display_header) { |
115 OutputString("\nDirect dependencies " | 148 OutputString( |
116 "(try also \"--all\" and \"--tree\"):\n"); | 149 "\nDirect dependencies " |
| 150 "(try also \"--all\", \"--tree\", or even \"--all --tree\"):\n"); |
117 } | 151 } |
118 | 152 |
119 const LabelTargetVector& target_deps = target->deps(); | 153 const LabelTargetVector& target_deps = target->deps(); |
120 for (size_t i = 0; i < target_deps.size(); i++) | 154 for (size_t i = 0; i < target_deps.size(); i++) |
121 deps.push_back(target_deps[i].label); | 155 deps.push_back(target_deps[i].label); |
122 | 156 |
123 const LabelTargetVector& target_datadeps = target->datadeps(); | 157 const LabelTargetVector& target_datadeps = target->datadeps(); |
124 for (size_t i = 0; i < target_datadeps.size(); i++) | 158 for (size_t i = 0; i < target_datadeps.size(); i++) |
125 deps.push_back(target_datadeps[i].label); | 159 deps.push_back(target_datadeps[i].label); |
126 } | 160 } |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 " configs\n" | 447 " configs\n" |
414 " Shows configs applied to the given target, sorted in the order\n" | 448 " Shows configs applied to the given target, sorted in the order\n" |
415 " they're specified. This includes both configs specified in the\n" | 449 " they're specified. This includes both configs specified in the\n" |
416 " \"configs\" variable, as well as configs pushed onto this target\n" | 450 " \"configs\" variable, as well as configs pushed onto this target\n" |
417 " via dependencies specifying \"all\" or \"direct\" dependent\n" | 451 " via dependencies specifying \"all\" or \"direct\" dependent\n" |
418 " configs.\n" | 452 " configs.\n" |
419 "\n" | 453 "\n" |
420 " deps [--all | --tree]\n" | 454 " deps [--all | --tree]\n" |
421 " Show immediate (or, when \"--all\" or \"--tree\" is specified,\n" | 455 " Show immediate (or, when \"--all\" or \"--tree\" is specified,\n" |
422 " recursive) dependencies of the given target. \"--tree\" shows them\n" | 456 " recursive) dependencies of the given target. \"--tree\" shows them\n" |
423 " in a tree format. Otherwise, they will be sorted alphabetically.\n" | 457 " in a tree format with duplicates elided (noted by \"...\").\n" |
424 " Both \"deps\" and \"datadeps\" will be included.\n" | 458 " \"--all\" shows them sorted alphabetically. Using both flags will\n" |
| 459 " print a tree with no omissions. Both \"deps\" and \"datadeps\"\n" |
| 460 " will be included.\n" |
425 "\n" | 461 "\n" |
426 " direct_dependent_configs\n" | 462 " direct_dependent_configs\n" |
427 " all_dependent_configs\n" | 463 " all_dependent_configs\n" |
428 " Shows the labels of configs applied to targets that depend on this\n" | 464 " Shows the labels of configs applied to targets that depend on this\n" |
429 " one (either directly or all of them).\n" | 465 " one (either directly or all of them).\n" |
430 "\n" | 466 "\n" |
431 " forward_dependent_configs_from\n" | 467 " forward_dependent_configs_from\n" |
432 " Shows the labels of dependencies for which dependent configs will\n" | 468 " Shows the labels of dependencies for which dependent configs will\n" |
433 " be pushed to targets depending on the current one.\n" | 469 " be pushed to targets depending on the current one.\n" |
434 "\n" | 470 "\n" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 // so always display them, even for groups and such. | 645 // so always display them, even for groups and such. |
610 PrintLibs(target, true); | 646 PrintLibs(target, true); |
611 PrintLibDirs(target, true); | 647 PrintLibDirs(target, true); |
612 | 648 |
613 PrintDeps(target, true); | 649 PrintDeps(target, true); |
614 | 650 |
615 return 0; | 651 return 0; |
616 } | 652 } |
617 | 653 |
618 } // namespace commands | 654 } // namespace commands |
OLD | NEW |