| 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" |
| 11 #include "tools/gn/config.h" | 11 #include "tools/gn/config.h" |
| 12 #include "tools/gn/config_values_extractors.h" | 12 #include "tools/gn/config_values_extractors.h" |
| 13 #include "tools/gn/item.h" | 13 #include "tools/gn/item.h" |
| 14 #include "tools/gn/item_node.h" | 14 #include "tools/gn/item_node.h" |
| 15 #include "tools/gn/label.h" | 15 #include "tools/gn/label.h" |
| 16 #include "tools/gn/setup.h" | 16 #include "tools/gn/setup.h" |
| 17 #include "tools/gn/standard_out.h" | 17 #include "tools/gn/standard_out.h" |
| 18 #include "tools/gn/target.h" | 18 #include "tools/gn/target.h" |
| 19 | 19 |
| 20 namespace commands { | 20 namespace commands { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 struct CompareTargetLabel { | |
| 25 bool operator()(const Target* a, const Target* b) const { | |
| 26 return a->label() < b->label(); | |
| 27 } | |
| 28 }; | |
| 29 | |
| 30 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result); | 24 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result); |
| 31 | 25 |
| 32 void RecursiveCollectDeps(const Target* target, std::set<Label>* result) { | 26 void RecursiveCollectDeps(const Target* target, std::set<Label>* result) { |
| 33 if (result->find(target->label()) != result->end()) | 27 if (result->find(target->label()) != result->end()) |
| 34 return; // Already did this target. | 28 return; // Already did this target. |
| 35 result->insert(target->label()); | 29 result->insert(target->label()); |
| 36 | 30 |
| 37 RecursiveCollectChildDeps(target, result); | 31 RecursiveCollectChildDeps(target, result); |
| 38 } | 32 } |
| 39 | 33 |
| 40 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { | 34 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { |
| 41 const std::vector<const Target*>& deps = target->deps(); | 35 const LabelTargetVector& deps = target->deps(); |
| 42 for (size_t i = 0; i < deps.size(); i++) | 36 for (size_t i = 0; i < deps.size(); i++) |
| 43 RecursiveCollectDeps(deps[i], result); | 37 RecursiveCollectDeps(deps[i].ptr, result); |
| 44 | 38 |
| 45 const std::vector<const Target*>& datadeps = target->datadeps(); | 39 const LabelTargetVector& datadeps = target->datadeps(); |
| 46 for (size_t i = 0; i < datadeps.size(); i++) | 40 for (size_t i = 0; i < datadeps.size(); i++) |
| 47 RecursiveCollectDeps(datadeps[i], result); | 41 RecursiveCollectDeps(datadeps[i].ptr, result); |
| 48 } | 42 } |
| 49 | 43 |
| 50 // Prints dependencies of the given target (not the target itself). | 44 // Prints dependencies of the given target (not the target itself). |
| 51 void RecursivePrintDeps(const Target* target, | 45 void RecursivePrintDeps(const Target* target, |
| 52 const Label& default_toolchain, | 46 const Label& default_toolchain, |
| 53 int indent_level) { | 47 int indent_level) { |
| 54 std::vector<const Target*> sorted_deps = target->deps(); | 48 LabelTargetVector sorted_deps = target->deps(); |
| 55 const std::vector<const Target*> datadeps = target->datadeps(); | 49 const LabelTargetVector& datadeps = target->datadeps(); |
| 56 for (size_t i = 0; i < datadeps.size(); i++) | 50 sorted_deps.insert(sorted_deps.end(), datadeps.begin(), datadeps.end()); |
| 57 sorted_deps.push_back(datadeps[i]); | 51 std::sort(sorted_deps.begin(), sorted_deps.end(), |
| 58 std::sort(sorted_deps.begin(), sorted_deps.end(), CompareTargetLabel()); | 52 LabelPtrLabelLess<Target>()); |
| 59 | 53 |
| 60 std::string indent(indent_level * 2, ' '); | 54 std::string indent(indent_level * 2, ' '); |
| 61 for (size_t i = 0; i < sorted_deps.size(); i++) { | 55 for (size_t i = 0; i < sorted_deps.size(); i++) { |
| 62 OutputString(indent + | 56 OutputString(indent + |
| 63 sorted_deps[i]->label().GetUserVisibleName(default_toolchain) + "\n"); | 57 sorted_deps[i].label.GetUserVisibleName(default_toolchain) + "\n"); |
| 64 RecursivePrintDeps(sorted_deps[i], default_toolchain, indent_level + 1); | 58 RecursivePrintDeps(sorted_deps[i].ptr, default_toolchain, indent_level + 1); |
| 65 } | 59 } |
| 66 } | 60 } |
| 67 | 61 |
| 68 void PrintDeps(const Target* target, bool display_header) { | 62 void PrintDeps(const Target* target, bool display_header) { |
| 69 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 63 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
| 70 Label toolchain_label = target->label().GetToolchainLabel(); | 64 Label toolchain_label = target->label().GetToolchainLabel(); |
| 71 | 65 |
| 72 // Tree mode is separate. | 66 // Tree mode is separate. |
| 73 if (cmdline->HasSwitch("tree")) { | 67 if (cmdline->HasSwitch("tree")) { |
| 74 if (display_header) | 68 if (display_header) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 87 RecursiveCollectChildDeps(target, &all_deps); | 81 RecursiveCollectChildDeps(target, &all_deps); |
| 88 for (std::set<Label>::iterator i = all_deps.begin(); | 82 for (std::set<Label>::iterator i = all_deps.begin(); |
| 89 i != all_deps.end(); ++i) | 83 i != all_deps.end(); ++i) |
| 90 deps.push_back(*i); | 84 deps.push_back(*i); |
| 91 } else { | 85 } else { |
| 92 if (display_header) { | 86 if (display_header) { |
| 93 OutputString("\nDirect dependencies " | 87 OutputString("\nDirect dependencies " |
| 94 "(try also \"--all\" and \"--tree\"):\n"); | 88 "(try also \"--all\" and \"--tree\"):\n"); |
| 95 } | 89 } |
| 96 | 90 |
| 97 const std::vector<const Target*>& target_deps = target->deps(); | 91 const LabelTargetVector& target_deps = target->deps(); |
| 98 for (size_t i = 0; i < target_deps.size(); i++) | 92 for (size_t i = 0; i < target_deps.size(); i++) |
| 99 deps.push_back(target_deps[i]->label()); | 93 deps.push_back(target_deps[i].label); |
| 100 | 94 |
| 101 const std::vector<const Target*>& target_datadeps = target->datadeps(); | 95 const LabelTargetVector& target_datadeps = target->datadeps(); |
| 102 for (size_t i = 0; i < target_datadeps.size(); i++) | 96 for (size_t i = 0; i < target_datadeps.size(); i++) |
| 103 deps.push_back(target_datadeps[i]->label()); | 97 deps.push_back(target_datadeps[i].label); |
| 104 } | 98 } |
| 105 | 99 |
| 106 std::sort(deps.begin(), deps.end()); | 100 std::sort(deps.begin(), deps.end()); |
| 107 for (size_t i = 0; i < deps.size(); i++) | 101 for (size_t i = 0; i < deps.size(); i++) |
| 108 OutputString(" " + deps[i].GetUserVisibleName(toolchain_label) + "\n"); | 102 OutputString(" " + deps[i].GetUserVisibleName(toolchain_label) + "\n"); |
| 109 } | 103 } |
| 110 | 104 |
| 111 // libs and lib_dirs are special in that they're inherited. We don't currently | 105 // libs and lib_dirs are special in that they're inherited. We don't currently |
| 112 // implement a blame feature for this since the bottom-up inheritance makes | 106 // implement a blame feature for this since the bottom-up inheritance makes |
| 113 // this difficult. | 107 // this difficult. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 134 for (size_t i = 0; i < libs.size(); i++) | 128 for (size_t i = 0; i < libs.size(); i++) |
| 135 OutputString(" " + libs[i] + "\n"); | 129 OutputString(" " + libs[i] + "\n"); |
| 136 } | 130 } |
| 137 | 131 |
| 138 void PrintConfigs(const Target* target, bool display_header) { | 132 void PrintConfigs(const Target* target, bool display_header) { |
| 139 // Configs (don't sort since the order determines how things are processed). | 133 // Configs (don't sort since the order determines how things are processed). |
| 140 if (display_header) | 134 if (display_header) |
| 141 OutputString("\nConfigs (in order applying):\n"); | 135 OutputString("\nConfigs (in order applying):\n"); |
| 142 | 136 |
| 143 Label toolchain_label = target->label().GetToolchainLabel(); | 137 Label toolchain_label = target->label().GetToolchainLabel(); |
| 144 const std::vector<const Config*>& configs = target->configs(); | 138 const LabelConfigVector& configs = target->configs(); |
| 145 for (size_t i = 0; i < configs.size(); i++) { | 139 for (size_t i = 0; i < configs.size(); i++) { |
| 146 OutputString(" " + | 140 OutputString(" " + |
| 147 configs[i]->label().GetUserVisibleName(toolchain_label) + "\n"); | 141 configs[i].label.GetUserVisibleName(toolchain_label) + "\n"); |
| 148 } | 142 } |
| 149 } | 143 } |
| 150 | 144 |
| 151 void PrintSources(const Target* target, bool display_header) { | 145 void PrintSources(const Target* target, bool display_header) { |
| 152 if (display_header) | 146 if (display_header) |
| 153 OutputString("\nSources:\n"); | 147 OutputString("\nSources:\n"); |
| 154 | 148 |
| 155 Target::FileList sources = target->sources(); | 149 Target::FileList sources = target->sources(); |
| 156 std::sort(sources.begin(), sources.end()); | 150 std::sort(sources.begin(), sources.end()); |
| 157 for (size_t i = 0; i < sources.size(); i++) | 151 for (size_t i = 0; i < sources.size(); i++) |
| 158 OutputString(" " + sources[i].value() + "\n"); | 152 OutputString(" " + sources[i].value() + "\n"); |
| 159 } | 153 } |
| 160 | 154 |
| 161 // Attempts to attribute the gen dependency of the given target to some source | 155 // Attribute the origin for attributing from where a target came from. Does |
| 162 // code and outputs the string to the output stream. | 156 // nothing if the input is null or it does not have a location. |
| 163 // | 157 void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) { |
| 164 // The attribution of the source of the dependencies is stored in the ItemNode | 158 if (!origin) |
| 165 // which is the parallel structure to the target dependency map, so we have | |
| 166 // to jump through a few loops to find everything. | |
| 167 void OutputSourceOfDep(const Target* target, | |
| 168 const Label& dep_label, | |
| 169 std::ostream& out) { | |
| 170 ItemTree& item_tree = target->settings()->build_settings()->item_tree(); | |
| 171 base::AutoLock lock(item_tree.lock()); | |
| 172 | |
| 173 const ItemNode* target_node = target->item_node(); | |
| 174 CHECK(target_node); | |
| 175 ItemNode* dep_node = item_tree.GetExistingNodeLocked(dep_label); | |
| 176 CHECK(dep_node); | |
| 177 | |
| 178 const ItemNode::ItemNodeMap& direct_deps = target_node->direct_dependencies(); | |
| 179 ItemNode::ItemNodeMap::const_iterator found = direct_deps.find(dep_node); | |
| 180 if (found == direct_deps.end()) | |
| 181 return; | 159 return; |
| 182 | 160 Location location = origin->GetRange().begin(); |
| 183 const Location& location = found->second.begin(); | |
| 184 out << " (Added by " + location.file()->name().value() << ":" | 161 out << " (Added by " + location.file()->name().value() << ":" |
| 185 << location.line_number() << ")\n"; | 162 << location.line_number() << ")\n"; |
| 186 } | 163 } |
| 187 | 164 |
| 188 // Templatized writer for writing out different config value types. | 165 // Templatized writer for writing out different config value types. |
| 189 template<typename T> struct DescValueWriter {}; | 166 template<typename T> struct DescValueWriter {}; |
| 190 template<> struct DescValueWriter<std::string> { | 167 template<> struct DescValueWriter<std::string> { |
| 191 void operator()(const std::string& str, std::ostream& out) const { | 168 void operator()(const std::string& str, std::ostream& out) const { |
| 192 out << " " << str << "\n"; | 169 out << " " << str << "\n"; |
| 193 } | 170 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 217 for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) { | 194 for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) { |
| 218 if ((iter.cur().*getter)().empty()) | 195 if ((iter.cur().*getter)().empty()) |
| 219 continue; | 196 continue; |
| 220 | 197 |
| 221 // Optional blame sub-head. | 198 // Optional blame sub-head. |
| 222 if (display_blame) { | 199 if (display_blame) { |
| 223 const Config* config = iter.GetCurrentConfig(); | 200 const Config* config = iter.GetCurrentConfig(); |
| 224 if (config) { | 201 if (config) { |
| 225 // Source of this value is a config. | 202 // Source of this value is a config. |
| 226 out << " From " << config->label().GetUserVisibleName(false) << "\n"; | 203 out << " From " << config->label().GetUserVisibleName(false) << "\n"; |
| 227 OutputSourceOfDep(target, config->label(), out); | 204 OutputSourceOfDep(iter.origin(), out); |
| 228 } else { | 205 } else { |
| 229 // Source of this value is the target itself. | 206 // Source of this value is the target itself. |
| 230 out << " From " << target->label().GetUserVisibleName(false) << "\n"; | 207 out << " From " << target->label().GetUserVisibleName(false) << "\n"; |
| 231 } | 208 } |
| 232 } | 209 } |
| 233 | 210 |
| 234 // Actual values. | 211 // Actual values. |
| 235 ConfigValuesToStream(iter.cur(), getter, writer, out); | 212 ConfigValuesToStream(iter.cur(), getter, writer, out); |
| 236 } | 213 } |
| 237 | 214 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 OUTPUT_CONFIG_VALUE(ldflags, std::string) | 363 OUTPUT_CONFIG_VALUE(ldflags, std::string) |
| 387 PrintLibs(target, true); | 364 PrintLibs(target, true); |
| 388 PrintLibDirs(target, true); | 365 PrintLibDirs(target, true); |
| 389 | 366 |
| 390 PrintDeps(target, true); | 367 PrintDeps(target, true); |
| 391 | 368 |
| 392 return 0; | 369 return 0; |
| 393 } | 370 } |
| 394 | 371 |
| 395 } // namespace commands | 372 } // namespace commands |
| OLD | NEW |