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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "tools/gn/commands.h" | 13 #include "tools/gn/commands.h" |
14 #include "tools/gn/config.h" | 14 #include "tools/gn/config.h" |
15 #include "tools/gn/config_values_extractors.h" | 15 #include "tools/gn/config_values_extractors.h" |
16 #include "tools/gn/deps_iterator.h" | 16 #include "tools/gn/deps_iterator.h" |
17 #include "tools/gn/filesystem_utils.h" | 17 #include "tools/gn/filesystem_utils.h" |
18 #include "tools/gn/item.h" | 18 #include "tools/gn/item.h" |
19 #include "tools/gn/label.h" | 19 #include "tools/gn/label.h" |
20 #include "tools/gn/runtime_deps.h" | 20 #include "tools/gn/runtime_deps.h" |
21 #include "tools/gn/setup.h" | 21 #include "tools/gn/setup.h" |
22 #include "tools/gn/standard_out.h" | 22 #include "tools/gn/standard_out.h" |
23 #include "tools/gn/substitution_writer.h" | 23 #include "tools/gn/substitution_writer.h" |
24 #include "tools/gn/switches.h" | |
24 #include "tools/gn/target.h" | 25 #include "tools/gn/target.h" |
25 #include "tools/gn/variables.h" | 26 #include "tools/gn/variables.h" |
26 | 27 |
27 namespace commands { | 28 namespace commands { |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 // Desc-specific command line switches. | 32 // Desc-specific command line switches. |
32 const char kBlame[] = "blame"; | 33 const char kBlame[] = "blame"; |
33 const char kTree[] = "tree"; | 34 const char kTree[] = "tree"; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 } | 113 } |
113 } | 114 } |
114 | 115 |
115 void PrintDeps(const Target* target, bool display_header) { | 116 void PrintDeps(const Target* target, bool display_header) { |
116 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); | 117 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); |
117 Label toolchain_label = target->label().GetToolchainLabel(); | 118 Label toolchain_label = target->label().GetToolchainLabel(); |
118 | 119 |
119 // Tree mode is separate. | 120 // Tree mode is separate. |
120 if (cmdline->HasSwitch(kTree)) { | 121 if (cmdline->HasSwitch(kTree)) { |
121 if (display_header) | 122 if (display_header) |
122 OutputString("\nDependency tree:\n"); | 123 OutputString("\nDependency tree\n"); |
123 | 124 |
124 if (cmdline->HasSwitch("all")) { | 125 if (cmdline->HasSwitch("all")) { |
125 // Show all tree deps with no eliding. | 126 // Show all tree deps with no eliding. |
126 RecursivePrintDeps(target, toolchain_label, nullptr, 1); | 127 RecursivePrintDeps(target, toolchain_label, nullptr, 1); |
127 } else { | 128 } else { |
128 // Don't recurse into duplicates. | 129 // Don't recurse into duplicates. |
129 std::set<const Target*> seen_targets; | 130 std::set<const Target*> seen_targets; |
130 RecursivePrintDeps(target, toolchain_label, &seen_targets, 1); | 131 RecursivePrintDeps(target, toolchain_label, &seen_targets, 1); |
131 } | 132 } |
132 return; | 133 return; |
133 } | 134 } |
134 | 135 |
135 // Collect the deps to display. | 136 // Collect the deps to display. |
136 if (cmdline->HasSwitch("all")) { | 137 if (cmdline->HasSwitch("all")) { |
137 // Show all dependencies. | 138 // Show all dependencies. |
138 if (display_header) | 139 if (display_header) |
139 OutputString("\nAll recursive dependencies:\n"); | 140 OutputString("\nAll recursive dependencies\n"); |
140 | 141 |
141 std::set<const Target*> all_deps; | 142 std::set<const Target*> all_deps; |
142 RecursiveCollectChildDeps(target, &all_deps); | 143 RecursiveCollectChildDeps(target, &all_deps); |
143 FilterAndPrintTargetSet(display_header, all_deps); | 144 FilterAndPrintTargetSet(display_header, all_deps); |
144 } else { | 145 } else { |
145 std::vector<const Target*> deps; | 146 std::vector<const Target*> deps; |
146 // Show direct dependencies only. | 147 // Show direct dependencies only. |
147 if (display_header) { | 148 if (display_header) { |
148 OutputString( | 149 OutputString( |
149 "\nDirect dependencies " | 150 "\nDirect dependencies " |
150 "(try also \"--all\", \"--tree\", or even \"--all --tree\"):\n"); | 151 "(try also \"--all\", \"--tree\", or even \"--all --tree\")\n"); |
151 } | 152 } |
152 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) | 153 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) |
153 deps.push_back(pair.ptr); | 154 deps.push_back(pair.ptr); |
154 std::sort(deps.begin(), deps.end()); | 155 std::sort(deps.begin(), deps.end()); |
155 FilterAndPrintTargets(display_header, &deps); | 156 FilterAndPrintTargets(display_header, &deps); |
156 } | 157 } |
157 } | 158 } |
158 | 159 |
159 // libs and lib_dirs are special in that they're inherited. We don't currently | 160 // libs and lib_dirs are special in that they're inherited. We don't currently |
160 // implement a blame feature for this since the bottom-up inheritance makes | 161 // implement a blame feature for this since the bottom-up inheritance makes |
(...skipping 17 matching lines...) Expand all Loading... | |
178 | 179 |
179 if (display_header) | 180 if (display_header) |
180 OutputString("\nlibs\n"); | 181 OutputString("\nlibs\n"); |
181 | 182 |
182 for (size_t i = 0; i < libs.size(); i++) | 183 for (size_t i = 0; i < libs.size(); i++) |
183 OutputString(" " + libs[i].value() + "\n"); | 184 OutputString(" " + libs[i].value() + "\n"); |
184 } | 185 } |
185 | 186 |
186 void PrintPublic(const Target* target, bool display_header) { | 187 void PrintPublic(const Target* target, bool display_header) { |
187 if (display_header) | 188 if (display_header) |
188 OutputString("\npublic:\n"); | 189 OutputString("\npublic\n"); |
189 | 190 |
190 if (target->all_headers_public()) { | 191 if (target->all_headers_public()) { |
191 OutputString(" [All headers listed in the sources are public.]\n"); | 192 OutputString(" [All headers listed in the sources are public.]\n"); |
192 return; | 193 return; |
193 } | 194 } |
194 | 195 |
195 Target::FileList public_headers = target->public_headers(); | 196 Target::FileList public_headers = target->public_headers(); |
196 std::sort(public_headers.begin(), public_headers.end()); | 197 std::sort(public_headers.begin(), public_headers.end()); |
197 for (const auto& hdr : public_headers) | 198 for (const auto& hdr : public_headers) |
198 OutputString(" " + hdr.value() + "\n"); | 199 OutputString(" " + hdr.value() + "\n"); |
199 } | 200 } |
200 | 201 |
201 void PrintCheckIncludes(const Target* target, bool display_header) { | 202 void PrintCheckIncludes(const Target* target, bool display_header) { |
202 if (display_header) | 203 if (display_header) |
203 OutputString("\ncheck_includes:\n"); | 204 OutputString("\ncheck_includes\n"); |
204 | 205 |
205 if (target->check_includes()) | 206 if (target->check_includes()) |
206 OutputString(" true\n"); | 207 OutputString(" true\n"); |
207 else | 208 else |
208 OutputString(" false\n"); | 209 OutputString(" false\n"); |
209 } | 210 } |
210 | 211 |
211 void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { | 212 void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { |
212 if (display_header) | 213 if (display_header) |
213 OutputString("\nallow_circular_includes_from:\n"); | 214 OutputString("\nallow_circular_includes_from\n"); |
214 | 215 |
215 Label toolchain_label = target->label().GetToolchainLabel(); | 216 Label toolchain_label = target->label().GetToolchainLabel(); |
216 for (const auto& cur : target->allow_circular_includes_from()) | 217 for (const auto& cur : target->allow_circular_includes_from()) |
217 OutputString(" " + cur.GetUserVisibleName(toolchain_label) + "\n"); | 218 OutputString(" " + cur.GetUserVisibleName(toolchain_label) + "\n"); |
218 } | 219 } |
219 | 220 |
220 void PrintVisibility(const Target* target, bool display_header) { | 221 void PrintVisibility(const Target* target, bool display_header) { |
221 if (display_header) | 222 if (display_header) |
222 OutputString("\nvisibility:\n"); | 223 OutputString("\nvisibility\n"); |
223 | 224 |
224 OutputString(target->visibility().Describe(2, false)); | 225 OutputString(target->visibility().Describe(2, false)); |
225 } | 226 } |
226 | 227 |
227 void PrintTestonly(const Target* target, bool display_header) { | 228 void PrintTestonly(const Target* target, bool display_header) { |
228 if (display_header) | 229 if (display_header) |
229 OutputString("\ntestonly:\n"); | 230 OutputString("\ntestonly\n"); |
230 | 231 |
231 if (target->testonly()) | 232 if (target->testonly()) |
232 OutputString(" true\n"); | 233 OutputString(" true\n"); |
233 else | 234 else |
234 OutputString(" false\n"); | 235 OutputString(" false\n"); |
235 } | 236 } |
236 | 237 |
237 // Recursively prints subconfigs of a config. | 238 // Recursively prints subconfigs of a config. |
238 void PrintSubConfigs(const Config* config, int indent_level) { | 239 void PrintSubConfigs(const Config* config, int indent_level) { |
239 if (config->configs().empty()) | 240 if (config->configs().empty()) |
240 return; | 241 return; |
241 | 242 |
242 std::string indent(indent_level * 2, ' '); | 243 std::string indent(indent_level * 2, ' '); |
243 Label toolchain_label = config->label().GetToolchainLabel(); | 244 Label toolchain_label = config->label().GetToolchainLabel(); |
244 for (const auto& pair : config->configs()) { | 245 for (const auto& pair : config->configs()) { |
245 OutputString( | 246 OutputString( |
246 indent + pair.label.GetUserVisibleName(toolchain_label) + "\n"); | 247 indent + pair.label.GetUserVisibleName(toolchain_label) + "\n"); |
247 PrintSubConfigs(pair.ptr, indent_level + 1); | 248 PrintSubConfigs(pair.ptr, indent_level + 1); |
248 } | 249 } |
249 } | 250 } |
250 | 251 |
251 // This allows configs stored as either std::vector<LabelConfigPair> or | 252 // This allows configs stored as either std::vector<LabelConfigPair> or |
252 // UniqueVector<LabelConfigPair> to be printed. | 253 // UniqueVector<LabelConfigPair> to be printed. |
253 template <class VectorType> | 254 template <class VectorType> |
254 void PrintConfigsVector(const Target* target, | 255 void PrintConfigsVector(const Item* item, |
255 const VectorType& configs, | 256 const VectorType& configs, |
256 const std::string& heading, | 257 const std::string& heading, |
257 bool display_header) { | 258 bool display_header) { |
258 if (configs.empty()) | 259 if (configs.empty()) |
259 return; | 260 return; |
260 | 261 |
261 bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree); | 262 bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree); |
262 | 263 |
263 // Don't sort since the order determines how things are processed. | 264 // Don't sort since the order determines how things are processed. |
264 if (display_header) { | 265 if (display_header) { |
265 if (tree) | 266 if (tree) |
266 OutputString("\n" + heading + " tree (in order applying):\n"); | 267 OutputString("\n" + heading + " tree (in order applying)\n"); |
267 else | 268 else |
268 OutputString("\n" + heading + " (in order applying, try also --tree):\n"); | 269 OutputString("\n" + heading + " (in order applying, try also --tree)\n"); |
269 } | 270 } |
270 | 271 |
271 Label toolchain_label = target->label().GetToolchainLabel(); | 272 Label toolchain_label = item->label().GetToolchainLabel(); |
272 for (const auto& config : configs) { | 273 for (const auto& config : configs) { |
273 OutputString(" " + config.label.GetUserVisibleName(toolchain_label) + | 274 OutputString(" " + config.label.GetUserVisibleName(toolchain_label) + |
274 "\n"); | 275 "\n"); |
275 if (tree) | 276 if (tree) |
276 PrintSubConfigs(config.ptr, 2); // 2 = start with double-indent. | 277 PrintSubConfigs(config.ptr, 2); // 2 = start with double-indent. |
277 } | 278 } |
278 } | 279 } |
279 | 280 |
280 void PrintConfigs(const Target* target, bool display_header) { | 281 void PrintConfigs(const Target* target, bool display_header) { |
281 PrintConfigsVector(target, target->configs().vector(), "configs", | 282 PrintConfigsVector(target, target->configs().vector(), "configs", |
282 display_header); | 283 display_header); |
283 } | 284 } |
284 | 285 |
286 void PrintConfigs(const Config* config, bool display_header) { | |
287 PrintConfigsVector(config, config->configs().vector(), "configs", | |
288 display_header); | |
289 } | |
290 | |
285 void PrintPublicConfigs(const Target* target, bool display_header) { | 291 void PrintPublicConfigs(const Target* target, bool display_header) { |
286 PrintConfigsVector(target, target->public_configs(), | 292 PrintConfigsVector(target, target->public_configs(), |
287 "public_configs", display_header); | 293 "public_configs", display_header); |
288 } | 294 } |
289 | 295 |
290 void PrintAllDependentConfigs(const Target* target, bool display_header) { | 296 void PrintAllDependentConfigs(const Target* target, bool display_header) { |
291 PrintConfigsVector(target, target->all_dependent_configs(), | 297 PrintConfigsVector(target, target->all_dependent_configs(), |
292 "all_dependent_configs", display_header); | 298 "all_dependent_configs", display_header); |
293 } | 299 } |
294 | 300 |
295 void PrintFileList(const Target::FileList& files, | 301 void PrintFileList(const Target::FileList& files, |
296 const std::string& header, | 302 const std::string& header, |
297 bool indent_extra, | 303 bool indent_extra, |
298 bool display_header) { | 304 bool display_header) { |
299 if (files.empty()) | 305 if (files.empty()) |
300 return; | 306 return; |
301 | 307 |
302 if (display_header) | 308 if (display_header) |
303 OutputString("\n" + header + ":\n"); | 309 OutputString("\n" + header + "\n"); |
304 | 310 |
305 std::string indent = indent_extra ? " " : " "; | 311 std::string indent = indent_extra ? " " : " "; |
306 | 312 |
307 Target::FileList sorted = files; | 313 Target::FileList sorted = files; |
308 std::sort(sorted.begin(), sorted.end()); | 314 std::sort(sorted.begin(), sorted.end()); |
309 for (const auto& elem : sorted) | 315 for (const auto& elem : sorted) |
310 OutputString(indent + elem.value() + "\n"); | 316 OutputString(indent + elem.value() + "\n"); |
311 } | 317 } |
312 | 318 |
313 void PrintSources(const Target* target, bool display_header) { | 319 void PrintSources(const Target* target, bool display_header) { |
314 PrintFileList(target->sources(), "sources", false, display_header); | 320 PrintFileList(target->sources(), "sources", false, display_header); |
315 } | 321 } |
316 | 322 |
317 void PrintInputs(const Target* target, bool display_header) { | 323 void PrintInputs(const Target* target, bool display_header) { |
318 PrintFileList(target->inputs(), "inputs", false, display_header); | 324 PrintFileList(target->inputs(), "inputs", false, display_header); |
319 } | 325 } |
320 | 326 |
321 void PrintOutputs(const Target* target, bool display_header) { | 327 void PrintOutputs(const Target* target, bool display_header) { |
322 if (display_header) | 328 if (display_header) |
323 OutputString("\noutputs:\n"); | 329 OutputString("\noutputs\n"); |
324 | 330 |
325 if (target->output_type() == Target::ACTION) { | 331 if (target->output_type() == Target::ACTION) { |
326 // Action, print out outputs, don't apply sources to it. | 332 // Action, print out outputs, don't apply sources to it. |
327 for (const auto& elem : target->action_values().outputs().list()) { | 333 for (const auto& elem : target->action_values().outputs().list()) { |
328 OutputString(" " + elem.AsString() + "\n"); | 334 OutputString(" " + elem.AsString() + "\n"); |
329 } | 335 } |
330 } else if (target->output_type() == Target::CREATE_BUNDLE) { | 336 } else if (target->output_type() == Target::CREATE_BUNDLE) { |
331 std::vector<SourceFile> output_files; | 337 std::vector<SourceFile> output_files; |
332 target->bundle_data().GetOutputsAsSourceFiles(target->settings(), | 338 target->bundle_data().GetOutputsAsSourceFiles(target->settings(), |
333 &output_files); | 339 &output_files); |
334 PrintFileList(output_files, "", true, false); | 340 PrintFileList(output_files, "", true, false); |
335 } else { | 341 } else { |
336 const SubstitutionList& outputs = target->action_values().outputs(); | 342 const SubstitutionList& outputs = target->action_values().outputs(); |
337 if (!outputs.required_types().empty()) { | 343 if (!outputs.required_types().empty()) { |
338 // Display the pattern and resolved pattern separately, since there are | 344 // Display the pattern and resolved pattern separately, since there are |
339 // subtitutions used. | 345 // subtitutions used. |
340 OutputString(" Output pattern:\n"); | 346 OutputString(" Output pattern\n"); |
341 for (const auto& elem : outputs.list()) | 347 for (const auto& elem : outputs.list()) |
342 OutputString(" " + elem.AsString() + "\n"); | 348 OutputString(" " + elem.AsString() + "\n"); |
343 | 349 |
344 // Now display what that resolves to given the sources. | 350 // Now display what that resolves to given the sources. |
345 OutputString("\n Resolved output file list:\n"); | 351 OutputString("\n Resolved output file list\n"); |
346 } | 352 } |
347 | 353 |
348 // Resolved output list. | 354 // Resolved output list. |
349 std::vector<SourceFile> output_files; | 355 std::vector<SourceFile> output_files; |
350 SubstitutionWriter::ApplyListToSources(target->settings(), outputs, | 356 SubstitutionWriter::ApplyListToSources(target->settings(), outputs, |
351 target->sources(), &output_files); | 357 target->sources(), &output_files); |
352 PrintFileList(output_files, "", true, false); | 358 PrintFileList(output_files, "", true, false); |
353 } | 359 } |
354 } | 360 } |
355 | 361 |
356 void PrintScript(const Target* target, bool display_header) { | 362 void PrintScript(const Target* target, bool display_header) { |
357 if (display_header) | 363 if (display_header) |
358 OutputString("\nscript:\n"); | 364 OutputString("\nscript\n"); |
359 OutputString(" " + target->action_values().script().value() + "\n"); | 365 OutputString(" " + target->action_values().script().value() + "\n"); |
360 } | 366 } |
361 | 367 |
362 void PrintArgs(const Target* target, bool display_header) { | 368 void PrintArgs(const Target* target, bool display_header) { |
363 if (display_header) | 369 if (display_header) |
364 OutputString("\nargs:\n"); | 370 OutputString("\nargs\n"); |
365 for (const auto& elem : target->action_values().args().list()) { | 371 for (const auto& elem : target->action_values().args().list()) { |
366 OutputString(" " + elem.AsString() + "\n"); | 372 OutputString(" " + elem.AsString() + "\n"); |
367 } | 373 } |
368 } | 374 } |
369 | 375 |
370 void PrintDepfile(const Target* target, bool display_header) { | 376 void PrintDepfile(const Target* target, bool display_header) { |
371 if (target->action_values().depfile().empty()) | 377 if (target->action_values().depfile().empty()) |
372 return; | 378 return; |
373 if (display_header) | 379 if (display_header) |
374 OutputString("\ndepfile:\n"); | 380 OutputString("\ndepfile\n"); |
375 OutputString(" " + target->action_values().depfile().AsString() + "\n"); | 381 OutputString(" " + target->action_values().depfile().AsString() + "\n"); |
376 } | 382 } |
377 | 383 |
378 // Attribute the origin for attributing from where a target came from. Does | 384 // Attribute the origin for attributing from where a target came from. Does |
379 // nothing if the input is null or it does not have a location. | 385 // nothing if the input is null or it does not have a location. |
380 void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) { | 386 void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) { |
381 if (!origin) | 387 if (!origin) |
382 return; | 388 return; |
383 Location location = origin->GetRange().begin(); | 389 Location location = origin->GetRange().begin(); |
384 out << " (Added by " + location.file()->name().value() << ":" | 390 out << " (Added by " + location.file()->name().value() << ":" |
385 << location.line_number() << ")\n"; | 391 << location.line_number() << ")\n"; |
386 } | 392 } |
387 | 393 |
388 // Templatized writer for writing out different config value types. | 394 // Templatized writer for writing out different config value types. |
389 template<typename T> struct DescValueWriter {}; | 395 template<typename T> struct DescValueWriter {}; |
390 template<> struct DescValueWriter<std::string> { | 396 template<> struct DescValueWriter<std::string> { |
391 void operator()(const std::string& str, std::ostream& out) const { | 397 void operator()(const std::string& str, std::ostream& out) const { |
392 out << " " << str << "\n"; | 398 out << " " << str << "\n"; |
393 } | 399 } |
394 }; | 400 }; |
395 template<> struct DescValueWriter<SourceDir> { | 401 template<> struct DescValueWriter<SourceDir> { |
396 void operator()(const SourceDir& dir, std::ostream& out) const { | 402 void operator()(const SourceDir& dir, std::ostream& out) const { |
397 out << " " << FormatSourceDir(dir) << "\n"; | 403 out << " " << FormatSourceDir(dir) << "\n"; |
398 } | 404 } |
399 }; | 405 }; |
406 template<> struct DescValueWriter<LibFile> { | |
407 void operator()(const LibFile& lib, std::ostream& out) const { | |
408 if (lib.is_source_file()) | |
409 out << " " << lib.source_file().value() << "\n"; | |
410 else | |
411 out << " " << lib.value() << "\n"; | |
412 } | |
413 }; | |
400 | 414 |
401 // Writes a given config value type to the string, optionally with attribution. | 415 // Writes a given config value type to the string, optionally with attribution. |
402 // This should match RecursiveTargetConfigToStream in the order it traverses. | 416 // This should match RecursiveTargetConfigToStream in the order it traverses. |
403 template<typename T> void OutputRecursiveTargetConfig( | 417 template<typename T> void OutputRecursiveTargetConfig( |
404 const Target* target, | 418 const Target* target, |
405 const char* header_name, | 419 const char* header_name, |
406 const std::vector<T>& (ConfigValues::* getter)() const) { | 420 const std::vector<T>& (ConfigValues::* getter)() const) { |
407 bool display_blame = | 421 bool display_blame = |
408 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); | 422 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); |
409 | 423 |
(...skipping 16 matching lines...) Expand all Loading... | |
426 out << " From " << target->label().GetUserVisibleName(false) << "\n"; | 440 out << " From " << target->label().GetUserVisibleName(false) << "\n"; |
427 } | 441 } |
428 } | 442 } |
429 | 443 |
430 // Actual values. | 444 // Actual values. |
431 ConfigValuesToStream(iter.cur(), getter, writer, out); | 445 ConfigValuesToStream(iter.cur(), getter, writer, out); |
432 } | 446 } |
433 | 447 |
434 std::string out_str = out.str(); | 448 std::string out_str = out.str(); |
435 if (!out_str.empty()) { | 449 if (!out_str.empty()) { |
436 OutputString("\n" + std::string(header_name) + "\n"); | 450 if (header_name) |
451 OutputString("\n" + std::string(header_name) + "\n"); | |
437 OutputString(out_str); | 452 OutputString(out_str); |
438 } | 453 } |
439 } | 454 } |
455 | |
456 template<typename T> void OutputConfigValueArray( | |
457 const ConfigValues& values, | |
458 const char* header_name, | |
459 const std::vector<T>& (ConfigValues::* getter)() const) { | |
460 std::ostringstream out; | |
461 | |
462 DescValueWriter<T> writer; | |
463 for (const T& cur : (values.*getter)()) | |
464 writer(cur, out); | |
465 | |
466 std::string out_str = out.str(); | |
467 if (!out_str.empty()) { | |
468 if (header_name) | |
469 OutputString("\n" + std::string(header_name) + "\n"); | |
470 OutputString(out_str); | |
471 } | |
472 } | |
440 | 473 |
441 void PrintRuntimeDeps(const Target* target) { | 474 void PrintRuntimeDeps(const Target* target) { |
442 bool display_blame = | 475 bool display_blame = |
443 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); | 476 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); |
444 Label toolchain = target->label().GetToolchainLabel(); | 477 Label toolchain = target->label().GetToolchainLabel(); |
445 | 478 |
446 const Target* previous_from = NULL; | 479 const Target* previous_from = NULL; |
447 for (const auto& pair : ComputeRuntimeDeps(target)) { | 480 for (const auto& pair : ComputeRuntimeDeps(target)) { |
448 if (display_blame) { | 481 if (display_blame) { |
449 // Generally a target's runtime deps will be listed sequentially, so | 482 // Generally a target's runtime deps will be listed sequentially, so |
450 // group them and don't duplicate the "from" label for two in a row. | 483 // group them and don't duplicate the "from" label for two in a row. |
451 if (previous_from == pair.second) { | 484 if (previous_from == pair.second) { |
452 OutputString(" "); // Just indent. | 485 OutputString(" "); // Just indent. |
453 } else { | 486 } else { |
454 previous_from = pair.second; | 487 previous_from = pair.second; |
455 OutputString("From "); | 488 OutputString("From "); |
456 OutputString(pair.second->label().GetUserVisibleName(toolchain)); | 489 OutputString(pair.second->label().GetUserVisibleName(toolchain)); |
457 OutputString("\n "); // Make the file name indented. | 490 OutputString("\n "); // Make the file name indented. |
458 } | 491 } |
459 } | 492 } |
460 OutputString(pair.first.value()); | 493 OutputString(pair.first.value()); |
461 OutputString("\n"); | 494 OutputString("\n"); |
462 } | 495 } |
463 } | 496 } |
464 | 497 |
498 // If "what" is empty, prints all PCH info. If "what" is nonempty, prints only | |
499 // the things that match (if any). REturns true if anything was printed. | |
Dirk Pranke
2016/04/30 00:27:54
nit: s/REturns/Returns/.
| |
500 bool PrintPrecompiledHeaderInfo(const ConfigValues& values, | |
501 const std::string& what, | |
502 bool display_headers) { | |
503 bool found_match = false; | |
504 if (what == "precompiled_header" || what.empty()) { | |
505 if (!values.precompiled_header().empty()) { | |
506 if (display_headers) | |
507 OutputString("\nprecompiled_header\n"); | |
508 OutputString(values.precompiled_header() + "\n"); | |
509 } | |
510 found_match = true; | |
511 } | |
512 if (what == "precompiled_source" || what.empty()) { | |
513 if (!values.precompiled_source().is_null()) { | |
514 if (display_headers) | |
515 OutputString("\nprecompiled_source\n"); | |
516 OutputString(values.precompiled_source().value() + "\n"); | |
517 } | |
518 found_match = true; | |
519 } | |
520 return found_match; | |
521 } | |
522 | |
523 bool PrintTarget(const Target* target, | |
524 const std::string& what, | |
525 bool display_target_header) { | |
526 if (display_target_header) { | |
527 OutputString("Target: ", DECORATION_YELLOW); | |
528 OutputString(target->label().GetUserVisibleName(false) + "\n"); | |
529 OutputString("Type: ", DECORATION_YELLOW); | |
530 OutputString(std::string( | |
531 Target::GetStringForOutputType(target->output_type())) + "\n"); | |
532 OutputString("Toolchain: ", DECORATION_YELLOW); | |
533 OutputString( | |
534 target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); | |
535 } | |
536 | |
537 // Display headers when outputting everything. | |
538 bool display_headers = what.empty(); | |
539 | |
540 bool found_match = false; | |
541 | |
542 // Display this only applicable to binary targets. | |
543 bool is_binary_output = | |
544 target->output_type() != Target::GROUP && | |
545 target->output_type() != Target::COPY_FILES && | |
546 target->output_type() != Target::ACTION && | |
547 target->output_type() != Target::ACTION_FOREACH && | |
548 target->output_type() != Target::BUNDLE_DATA && | |
549 target->output_type() != Target::CREATE_BUNDLE; | |
550 | |
551 // General target meta variables. | |
552 if (what.empty() || what == variables::kVisibility) { | |
553 PrintVisibility(target, display_headers); | |
554 found_match = true; | |
555 } | |
556 if (what.empty() || what == variables::kTestonly) { | |
557 PrintTestonly(target, display_headers); | |
558 found_match = true; | |
559 } | |
560 | |
561 // Binary target meta variables. | |
562 if (is_binary_output) { | |
563 if (what.empty() || what == variables::kCheckIncludes) { | |
564 PrintCheckIncludes(target, display_headers); | |
565 found_match = true; | |
566 } | |
567 if (what.empty() || what == variables::kAllowCircularIncludesFrom) { | |
568 PrintAllowCircularIncludesFrom(target, display_headers); | |
569 found_match = true; | |
570 } | |
571 } | |
572 | |
573 // Sources and inputs. | |
574 if (what.empty() || what == variables::kSources) { | |
575 PrintSources(target, display_headers); | |
576 found_match = true; | |
577 } | |
578 if (what.empty() || what == variables::kPublic) { | |
579 PrintPublic(target, display_headers); | |
580 found_match = true; | |
581 } | |
582 if (what.empty() || what == variables::kInputs) { | |
583 PrintInputs(target, display_headers); | |
584 found_match = true; | |
585 } | |
586 | |
587 // Configs. Configs set directly on a target are only relevant for binary | |
588 // targets | |
589 if (is_binary_output && (what.empty() || what == variables::kConfigs)) { | |
590 PrintConfigs(target, display_headers); | |
591 found_match = true; | |
592 } | |
593 | |
594 // Dependent/public configs can be applied to anything. | |
595 if (what.empty() || what == variables::kPublicConfigs) { | |
596 PrintPublicConfigs(target, display_headers); | |
597 found_match = true; | |
598 } | |
599 if (what.empty() || what == variables::kAllDependentConfigs) { | |
600 PrintAllDependentConfigs(target, display_headers); | |
601 found_match = true; | |
602 } | |
603 | |
604 // Action values. | |
605 if (target->output_type() == Target::ACTION || | |
606 target->output_type() == Target::ACTION_FOREACH) { | |
607 if (what == variables::kScript) { | |
608 PrintScript(target, display_headers); | |
609 found_match = true; | |
610 } | |
611 if (what == variables::kArgs) { | |
612 PrintArgs(target, display_headers); | |
613 found_match = true; | |
614 } | |
615 if (what.empty() || what == variables::kDepfile) { | |
616 PrintDepfile(target, display_headers); | |
617 found_match = true; | |
618 } | |
619 } | |
620 | |
621 // Outputs. | |
622 if (target->output_type() == Target::ACTION || | |
623 target->output_type() == Target::ACTION_FOREACH || | |
624 target->output_type() == Target::COPY_FILES || | |
625 target->output_type() == Target::CREATE_BUNDLE) { | |
626 if (what.empty() || what == variables::kOutputs) { | |
627 PrintOutputs(target, display_headers); | |
628 found_match = true; | |
629 } | |
630 } | |
631 | |
632 // Values from configs only apply to binary targets. | |
633 if (is_binary_output) { | |
634 #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ | |
635 if (what.empty() || what == #name) { \ | |
636 OutputRecursiveTargetConfig<type>( \ | |
637 target, display_headers ? #name : nullptr, &ConfigValues::name); \ | |
638 found_match = true; \ | |
639 } | |
640 | |
641 CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) | |
642 CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) | |
643 CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) | |
644 CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) | |
645 CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) | |
646 CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) | |
647 CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) | |
648 CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) | |
649 CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) | |
650 CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) | |
651 // Libs and lib_dirs are handled specially below. | |
652 | |
653 #undef CONFIG_VALUE_ARRAY_HANDLER | |
654 | |
655 found_match |= PrintPrecompiledHeaderInfo(target->config_values(), | |
656 what, display_headers); | |
657 } | |
658 | |
659 // Deps | |
660 if (what.empty() || what == "deps") { | |
661 PrintDeps(target, display_headers); | |
662 found_match = true; | |
663 } | |
664 | |
665 // Runtime deps are special, print only when explicitly asked for and not in | |
666 // overview mode. | |
667 if (what == "runtime_deps") { | |
668 PrintRuntimeDeps(target); | |
669 found_match = true; | |
670 } | |
671 | |
672 // Libs can be part of any target and get recursively pushed up the chain, | |
673 // so display them regardless of target type. | |
674 if (what.empty() || what == variables::kLibs) { | |
675 PrintLibs(target, display_headers); | |
676 found_match = true; | |
677 } | |
678 if (what.empty() || what == variables::kLibDirs) { | |
679 PrintLibDirs(target, display_headers); | |
680 found_match = true; | |
681 } | |
682 | |
683 if (!found_match) { | |
684 OutputString("Don't know how to display \"" + what + "\" for \"" + | |
685 Target::GetStringForOutputType(target->output_type()) + "\".\n"); | |
686 return false; | |
687 } | |
688 return true; | |
689 } | |
690 | |
691 bool PrintConfig(const Config* config, | |
692 const std::string& what, | |
693 bool display_config_header) { | |
694 const ConfigValues& values = config->resolved_values(); | |
695 | |
696 if (display_config_header) { | |
697 OutputString("Config: ", DECORATION_YELLOW); | |
698 OutputString(config->label().GetUserVisibleName(false) + "\n"); | |
699 OutputString("Toolchain: ", DECORATION_YELLOW); | |
700 OutputString( | |
701 config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); | |
702 if (what.empty() && !config->configs().empty()) { | |
703 OutputString( | |
704 "(This is a composite config, the values below are after the\n" | |
705 "expansion of the child configs.)\n"); | |
706 } | |
707 } | |
708 | |
709 // Display headers when outputting everything. | |
710 bool display_headers = what.empty(); | |
711 | |
712 if (what.empty() || what == variables::kConfigs) | |
713 PrintConfigs(config, display_headers); | |
714 | |
715 #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ | |
716 if (what.empty() || what == #name) { \ | |
717 OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \ | |
718 &ConfigValues::name); \ | |
719 found_match = true; \ | |
720 } | |
721 | |
722 bool found_match = false; | |
723 | |
724 CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) | |
725 CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) | |
726 CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) | |
727 CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) | |
728 CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) | |
729 CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) | |
730 CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) | |
731 CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) | |
732 CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) | |
733 CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) | |
734 CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir) | |
735 CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile) | |
736 | |
737 #undef CONFIG_VALUE_ARRAY_HANDLER | |
738 | |
739 // Handles all PCH-related variables. | |
740 found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(), | |
741 what, display_headers); | |
742 | |
743 if (!found_match) { | |
744 OutputString("Don't know how to display \"" + what + "\" for a config.\n"); | |
745 return false; | |
746 } | |
747 return true; | |
748 } | |
749 | |
465 } // namespace | 750 } // namespace |
466 | 751 |
467 // desc ------------------------------------------------------------------------ | 752 // desc ------------------------------------------------------------------------ |
468 | 753 |
469 const char kDesc[] = "desc"; | 754 const char kDesc[] = "desc"; |
470 const char kDesc_HelpShort[] = | 755 const char kDesc_HelpShort[] = |
471 "desc: Show lots of insightful information about a target."; | 756 "desc: Show lots of insightful information about a target or config."; |
472 const char kDesc_Help[] = | 757 const char kDesc_Help[] = |
473 "gn desc <out_dir> <target label> [<what to show>] [--blame]\n" | 758 "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n" |
474 "\n" | 759 "\n" |
475 " Displays information about a given labeled target for the given build.\n" | 760 " Displays information about a given target or config. The build\n" |
476 " The build parameters will be taken for the build in the given\n" | 761 " build parameters will be taken for the build in the given <out_dir>.\n" |
477 " <out_dir>.\n" | 762 "\n" |
763 " The <label or pattern> can be a target label, a config label, or a\n" | |
764 " label pattern (see \"gn help label_pattern\"). A label pattern will\n" | |
765 " only match targets.\n" | |
478 "\n" | 766 "\n" |
479 "Possibilities for <what to show>\n" | 767 "Possibilities for <what to show>\n" |
768 "\n" | |
480 " (If unspecified an overall summary will be displayed.)\n" | 769 " (If unspecified an overall summary will be displayed.)\n" |
481 "\n" | 770 "\n" |
482 " sources\n" | 771 " all_dependent_configs\n" |
483 " Source files.\n" | 772 " allow_circular_includes_from\n" |
484 "\n" | 773 " arflags [--blame]\n" |
774 " args\n" | |
775 " cflags [--blame]\n" | |
776 " cflags_cc [--blame]\n" | |
777 " cflags_cxx [--blame]\n" | |
778 " check_includes\n" | |
779 " configs [--tree] (see below)\n" | |
780 " defines [--blame]\n" | |
781 " depfile\n" | |
782 " deps [--all] [--tree] (see below)\n" | |
783 " include_dirs [--blame]\n" | |
485 " inputs\n" | 784 " inputs\n" |
486 " Additional input dependencies.\n" | 785 " ldflags [--blame]\n" |
487 "\n" | |
488 " public\n" | |
489 " Public header files.\n" | |
490 "\n" | |
491 " check_includes\n" | |
492 " Whether \"gn check\" checks this target for include usage.\n" | |
493 "\n" | |
494 " allow_circular_includes_from\n" | |
495 " Permit includes from these targets.\n" | |
496 "\n" | |
497 " visibility\n" | |
498 " Prints which targets can depend on this one.\n" | |
499 "\n" | |
500 " testonly\n" | |
501 " Whether this target may only be used in tests.\n" | |
502 "\n" | |
503 " configs\n" | |
504 " Shows configs applied to the given target, sorted in the order\n" | |
505 " they're specified. This includes both configs specified in the\n" | |
506 " \"configs\" variable, as well as configs pushed onto this target\n" | |
507 " via dependencies specifying \"all\" or \"direct\" dependent\n" | |
508 " configs.\n" | |
509 "\n" | |
510 " deps\n" | |
511 " Show immediate or recursive dependencies. See below for flags that\n" | |
512 " control deps printing.\n" | |
513 "\n" | |
514 " public_configs\n" | |
515 " all_dependent_configs\n" | |
516 " Shows the labels of configs applied to targets that depend on this\n" | |
517 " one (either directly or all of them).\n" | |
518 "\n" | |
519 " script\n" | |
520 " args\n" | |
521 " depfile\n" | |
522 " Actions only. The script and related values.\n" | |
523 "\n" | |
524 " outputs\n" | |
525 " Outputs for script and copy target types.\n" | |
526 "\n" | |
527 " arflags [--blame]\n" | |
528 " defines [--blame]\n" | |
529 " include_dirs [--blame]\n" | |
530 " cflags [--blame]\n" | |
531 " cflags_cc [--blame]\n" | |
532 " cflags_cxx [--blame]\n" | |
533 " ldflags [--blame]\n" | |
534 " lib_dirs\n" | 786 " lib_dirs\n" |
535 " libs\n" | 787 " libs\n" |
536 " Shows the given values taken from the target and all configs\n" | 788 " outputs\n" |
537 " applying. See \"--blame\" below.\n" | 789 " public_configs\n" |
790 " public\n" | |
791 " script\n" | |
792 " sources\n" | |
793 " testonly\n" | |
794 " visibility\n" | |
538 "\n" | 795 "\n" |
539 " runtime_deps\n" | 796 " runtime_deps\n" |
540 " Compute all runtime deps for the given target. This is a\n" | 797 " Compute all runtime deps for the given target. This is a\n" |
541 " computed list and does not correspond to any GN variable, unlike\n" | 798 " computed list and does not correspond to any GN variable, unlike\n" |
542 " most other values here.\n" | 799 " most other values here.\n" |
543 "\n" | 800 "\n" |
544 " The output is a list of file names relative to the build\n" | 801 " The output is a list of file names relative to the build\n" |
545 " directory. See \"gn help runtime_deps\" for how this is computed.\n" | 802 " directory. See \"gn help runtime_deps\" for how this is computed.\n" |
546 " This also works with \"--blame\" to see the source of the\n" | 803 " This also works with \"--blame\" to see the source of the\n" |
547 " dependency.\n" | 804 " dependency.\n" |
548 "\n" | 805 "\n" |
549 "Shared flags\n" | 806 "Shared flags\n" |
550 "\n" | 807 "\n" |
808 ALL_TOOLCHAINS_SWITCH_HELP | |
809 "\n" | |
810 "Target flags\n" | |
811 "\n" | |
551 " --blame\n" | 812 " --blame\n" |
552 " Used with any value specified by a config, this will name\n" | 813 " Used with any value specified on a config, this will name\n" |
553 " the config that specified the value. This doesn't currently work\n" | 814 " the config that cause that target to get the flag. This doesn't\n" |
554 " for libs and lib_dirs because those are inherited and are more\n" | 815 " currently work for libs and lib_dirs because those are inherited\n" |
555 " complicated to figure out the blame (patches welcome).\n" | 816 " and are more complicated to figure out the blame (patches\n" |
817 " welcome).\n" | |
556 "\n" | 818 "\n" |
557 "Flags that control how deps are printed\n" | 819 "Configs\n" |
820 "\n" | |
821 " The \"configs\" section will list all configs that apply. For targets\n" | |
822 " this will include configs specified in the \"configs\" variable of\n" | |
823 " the target, and also configs pushed onto this target via public\n" | |
824 " or \"all dependent\" configs.\n" | |
825 "\n" | |
826 " Configs can have child configs. Specifying --tree will show the\n" | |
827 " hierarchy.\n" | |
828 "\n" | |
829 "Printing deps\n" | |
830 "\n" | |
831 " Deps will include all public, private, and data deps (TODO this could\n" | |
832 " be clarified and enhanced) sorted in order applying. The following\n" | |
833 " may be used:\n" | |
558 "\n" | 834 "\n" |
559 " --all\n" | 835 " --all\n" |
560 " Collects all recursive dependencies and prints a sorted flat list.\n" | 836 " Collects all recursive dependencies and prints a sorted flat list.\n" |
561 " Also usable with --tree (see below).\n" | 837 " Also usable with --tree (see below).\n" |
562 "\n" | 838 "\n" |
563 TARGET_PRINTING_MODE_COMMAND_LINE_HELP | 839 TARGET_PRINTING_MODE_COMMAND_LINE_HELP |
564 "\n" | 840 "\n" |
565 TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP | 841 TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP |
566 "\n" | 842 "\n" |
567 " --tree\n" | 843 " --tree\n" |
(...skipping 23 matching lines...) Expand all Loading... | |
591 " Summarizes the given target.\n" | 867 " Summarizes the given target.\n" |
592 "\n" | 868 "\n" |
593 " gn desc out/Foo :base_unittests deps --tree\n" | 869 " gn desc out/Foo :base_unittests deps --tree\n" |
594 " Shows a dependency tree of the \"base_unittests\" project in\n" | 870 " Shows a dependency tree of the \"base_unittests\" project in\n" |
595 " the current directory.\n" | 871 " the current directory.\n" |
596 "\n" | 872 "\n" |
597 " gn desc out/Debug //base defines --blame\n" | 873 " gn desc out/Debug //base defines --blame\n" |
598 " Shows defines set for the //base:base target, annotated by where\n" | 874 " Shows defines set for the //base:base target, annotated by where\n" |
599 " each one was set from.\n"; | 875 " each one was set from.\n"; |
600 | 876 |
601 #define OUTPUT_CONFIG_VALUE(name, type) \ | |
602 OutputRecursiveTargetConfig<type>(target, #name, &ConfigValues::name); | |
603 | |
604 int RunDesc(const std::vector<std::string>& args) { | 877 int RunDesc(const std::vector<std::string>& args) { |
605 if (args.size() != 2 && args.size() != 3) { | 878 if (args.size() != 2 && args.size() != 3) { |
606 Err(Location(), "You're holding it wrong.", | 879 Err(Location(), "You're holding it wrong.", |
607 "Usage: \"gn desc <out_dir> <target_name> [<what to display>]\"") | 880 "Usage: \"gn desc <out_dir> <target_name> [<what to display>]\"") |
608 .PrintToStdout(); | 881 .PrintToStdout(); |
609 return 1; | 882 return 1; |
610 } | 883 } |
884 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); | |
611 | 885 |
612 // Deliberately leaked to avoid expensive process teardown. | 886 // Deliberately leaked to avoid expensive process teardown. |
613 Setup* setup = new Setup; | 887 Setup* setup = new Setup; |
614 setup->build_settings().set_check_for_bad_items(false); | 888 setup->build_settings().set_check_for_bad_items(false); |
615 if (!setup->DoSetup(args[0], false)) | 889 if (!setup->DoSetup(args[0], false)) |
616 return 1; | 890 return 1; |
617 if (!setup->Run()) | 891 if (!setup->Run()) |
618 return 1; | 892 return 1; |
619 | 893 |
620 const Target* target = ResolveTargetFromCommandLineString(setup, args[1]); | 894 // Resolve target(s) and config from inputs. |
621 if (!target) | 895 UniqueVector<const Target*> target_matches; |
896 UniqueVector<const Config*> config_matches; | |
897 UniqueVector<const Toolchain*> toolchain_matches; | |
898 UniqueVector<SourceFile> file_matches; | |
899 | |
900 std::vector<std::string> target_list; | |
901 target_list.push_back(args[1]); | |
902 | |
903 if (!ResolveFromCommandLineInput( | |
904 setup, target_list, cmdline->HasSwitch(switches::kAllToolchains), | |
905 &target_matches, &config_matches, &toolchain_matches, &file_matches)) | |
622 return 1; | 906 return 1; |
623 | 907 |
624 #define CONFIG_VALUE_HANDLER(name, type) \ | 908 std::string what_to_print; |
625 } else if (what == #name) { OUTPUT_CONFIG_VALUE(name, type) | 909 if (args.size() == 3) |
910 what_to_print = args[2]; | |
626 | 911 |
627 if (args.size() == 3) { | 912 bool multiple_outputs = target_matches.size() + config_matches.size() > 1; |
628 // User specified one thing to display. | |
629 const std::string& what = args[2]; | |
630 if (what == variables::kConfigs) { | |
631 PrintConfigs(target, false); | |
632 } else if (what == variables::kPublicConfigs) { | |
633 PrintPublicConfigs(target, false); | |
634 } else if (what == variables::kAllDependentConfigs) { | |
635 PrintAllDependentConfigs(target, false); | |
636 } else if (what == variables::kSources) { | |
637 PrintSources(target, false); | |
638 } else if (what == variables::kPublic) { | |
639 PrintPublic(target, false); | |
640 } else if (what == variables::kCheckIncludes) { | |
641 PrintCheckIncludes(target, false); | |
642 } else if (what == variables::kAllowCircularIncludesFrom) { | |
643 PrintAllowCircularIncludesFrom(target, false); | |
644 } else if (what == variables::kVisibility) { | |
645 PrintVisibility(target, false); | |
646 } else if (what == variables::kTestonly) { | |
647 PrintTestonly(target, false); | |
648 } else if (what == variables::kInputs) { | |
649 PrintInputs(target, false); | |
650 } else if (what == variables::kScript) { | |
651 PrintScript(target, false); | |
652 } else if (what == variables::kArgs) { | |
653 PrintArgs(target, false); | |
654 } else if (what == variables::kDepfile) { | |
655 PrintDepfile(target, false); | |
656 } else if (what == variables::kOutputs) { | |
657 PrintOutputs(target, false); | |
658 } else if (what == variables::kDeps) { | |
659 PrintDeps(target, false); | |
660 } else if (what == variables::kLibDirs) { | |
661 PrintLibDirs(target, false); | |
662 } else if (what == variables::kLibs) { | |
663 PrintLibs(target, false); | |
664 } else if (what == "runtime_deps") { | |
665 PrintRuntimeDeps(target); | |
666 // } Hidden closing brace in macro below. | |
667 | 913 |
668 CONFIG_VALUE_HANDLER(defines, std::string) | 914 // Display headers for each target when printing all values, or when printing |
669 CONFIG_VALUE_HANDLER(include_dirs, SourceDir) | 915 // multiple targets or configs. |
670 CONFIG_VALUE_HANDLER(arflags, std::string) | 916 bool display_item_header = multiple_outputs || what_to_print.empty(); |
671 CONFIG_VALUE_HANDLER(asmflags, std::string) | |
672 CONFIG_VALUE_HANDLER(cflags, std::string) | |
673 CONFIG_VALUE_HANDLER(cflags_c, std::string) | |
674 CONFIG_VALUE_HANDLER(cflags_cc, std::string) | |
675 CONFIG_VALUE_HANDLER(cflags_objc, std::string) | |
676 CONFIG_VALUE_HANDLER(cflags_objcc, std::string) | |
677 CONFIG_VALUE_HANDLER(ldflags, std::string) | |
678 | 917 |
679 } else { | 918 bool printed_output = false; |
680 OutputString("Don't know how to display \"" + what + "\".\n"); | 919 for (const Target* target : target_matches) { |
920 if (printed_output) | |
921 OutputString("\n\n"); | |
922 printed_output = true; | |
923 | |
924 if (!PrintTarget(target, what_to_print, display_item_header)) | |
681 return 1; | 925 return 1; |
682 } | 926 } |
927 for (const Config* config : config_matches) { | |
928 if (printed_output) | |
929 OutputString("\n\n"); | |
930 printed_output = true; | |
683 | 931 |
684 #undef CONFIG_VALUE_HANDLER | 932 if (!PrintConfig(config, what_to_print, display_item_header)) |
685 return 0; | 933 return 1; |
686 } | 934 } |
687 | 935 |
688 // Display summary. | |
689 | |
690 // Display this only applicable to binary targets. | |
691 bool is_binary_output = | |
692 target->output_type() != Target::GROUP && | |
693 target->output_type() != Target::COPY_FILES && | |
694 target->output_type() != Target::ACTION && | |
695 target->output_type() != Target::ACTION_FOREACH && | |
696 target->output_type() != Target::BUNDLE_DATA && | |
697 target->output_type() != Target::CREATE_BUNDLE; | |
698 | |
699 // Generally we only want to display toolchains on labels when the toolchain | |
700 // is different than the default one for this target (which we always print | |
701 // in the header). | |
702 Label target_toolchain = target->label().GetToolchainLabel(); | |
703 | |
704 // Header. | |
705 OutputString("Target: ", DECORATION_YELLOW); | |
706 OutputString(target->label().GetUserVisibleName(false) + "\n"); | |
707 OutputString("Type: ", DECORATION_YELLOW); | |
708 OutputString(std::string( | |
709 Target::GetStringForOutputType(target->output_type())) + "\n"); | |
710 OutputString("Toolchain: ", DECORATION_YELLOW); | |
711 OutputString(target_toolchain.GetUserVisibleName(false) + "\n"); | |
712 | |
713 PrintSources(target, true); | |
714 if (is_binary_output) { | |
715 PrintPublic(target, true); | |
716 PrintCheckIncludes(target, true); | |
717 PrintAllowCircularIncludesFrom(target, true); | |
718 } | |
719 PrintVisibility(target, true); | |
720 if (is_binary_output) { | |
721 PrintTestonly(target, true); | |
722 PrintConfigs(target, true); | |
723 } | |
724 | |
725 PrintPublicConfigs(target, true); | |
726 PrintAllDependentConfigs(target, true); | |
727 | |
728 PrintInputs(target, true); | |
729 | |
730 if (is_binary_output) { | |
731 OUTPUT_CONFIG_VALUE(defines, std::string) | |
732 OUTPUT_CONFIG_VALUE(include_dirs, SourceDir) | |
733 OUTPUT_CONFIG_VALUE(asmflags, std::string) | |
734 OUTPUT_CONFIG_VALUE(cflags, std::string) | |
735 OUTPUT_CONFIG_VALUE(cflags_c, std::string) | |
736 OUTPUT_CONFIG_VALUE(cflags_cc, std::string) | |
737 OUTPUT_CONFIG_VALUE(cflags_objc, std::string) | |
738 OUTPUT_CONFIG_VALUE(cflags_objcc, std::string) | |
739 | |
740 if (target->output_type() == Target::STATIC_LIBRARY) | |
741 OUTPUT_CONFIG_VALUE(arflags, std::string) | |
742 else if (target->output_type() != Target::SOURCE_SET) | |
743 OUTPUT_CONFIG_VALUE(ldflags, std::string) | |
744 } | |
745 | |
746 if (target->output_type() == Target::ACTION || | |
747 target->output_type() == Target::ACTION_FOREACH) { | |
748 PrintScript(target, true); | |
749 PrintArgs(target, true); | |
750 PrintDepfile(target, true); | |
751 } | |
752 | |
753 if (target->output_type() == Target::ACTION || | |
754 target->output_type() == Target::ACTION_FOREACH || | |
755 target->output_type() == Target::COPY_FILES || | |
756 target->output_type() == Target::CREATE_BUNDLE) { | |
757 PrintOutputs(target, true); | |
758 } | |
759 | |
760 // Libs can be part of any target and get recursively pushed up the chain, | |
761 // so always display them, even for groups and such. | |
762 PrintLibs(target, true); | |
763 PrintLibDirs(target, true); | |
764 | |
765 PrintDeps(target, true); | |
766 | |
767 return 0; | 936 return 0; |
768 } | 937 } |
769 | 938 |
770 } // namespace commands | 939 } // namespace commands |
OLD | NEW |