Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: tools/gn/command_desc.cc

Issue 1934003002: Enhance GN's "desc" command to support configs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: typos Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/gn/command_ls.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 };
401
395 template<> struct DescValueWriter<SourceDir> { 402 template<> struct DescValueWriter<SourceDir> {
396 void operator()(const SourceDir& dir, std::ostream& out) const { 403 void operator()(const SourceDir& dir, std::ostream& out) const {
397 out << " " << FormatSourceDir(dir) << "\n"; 404 out << " " << FormatSourceDir(dir) << "\n";
398 } 405 }
399 }; 406 };
400 407
408 template<> struct DescValueWriter<LibFile> {
409 void operator()(const LibFile& lib, std::ostream& out) const {
410 if (lib.is_source_file())
411 out << " " << lib.source_file().value() << "\n";
412 else
413 out << " " << lib.value() << "\n";
414 }
415 };
416
401 // Writes a given config value type to the string, optionally with attribution. 417 // Writes a given config value type to the string, optionally with attribution.
402 // This should match RecursiveTargetConfigToStream in the order it traverses. 418 // This should match RecursiveTargetConfigToStream in the order it traverses.
403 template<typename T> void OutputRecursiveTargetConfig( 419 template<typename T> void OutputRecursiveTargetConfig(
404 const Target* target, 420 const Target* target,
405 const char* header_name, 421 const char* header_name,
406 const std::vector<T>& (ConfigValues::* getter)() const) { 422 const std::vector<T>& (ConfigValues::* getter)() const) {
407 bool display_blame = 423 bool display_blame =
408 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); 424 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
409 425
410 DescValueWriter<T> writer; 426 DescValueWriter<T> writer;
(...skipping 15 matching lines...) Expand all
426 out << " From " << target->label().GetUserVisibleName(false) << "\n"; 442 out << " From " << target->label().GetUserVisibleName(false) << "\n";
427 } 443 }
428 } 444 }
429 445
430 // Actual values. 446 // Actual values.
431 ConfigValuesToStream(iter.cur(), getter, writer, out); 447 ConfigValuesToStream(iter.cur(), getter, writer, out);
432 } 448 }
433 449
434 std::string out_str = out.str(); 450 std::string out_str = out.str();
435 if (!out_str.empty()) { 451 if (!out_str.empty()) {
436 OutputString("\n" + std::string(header_name) + "\n"); 452 if (header_name)
453 OutputString("\n" + std::string(header_name) + "\n");
437 OutputString(out_str); 454 OutputString(out_str);
438 } 455 }
439 } 456 }
457
458 template<typename T> void OutputConfigValueArray(
459 const ConfigValues& values,
460 const char* header_name,
461 const std::vector<T>& (ConfigValues::* getter)() const) {
462 std::ostringstream out;
463
464 DescValueWriter<T> writer;
465 for (const T& cur : (values.*getter)())
466 writer(cur, out);
467
468 std::string out_str = out.str();
469 if (!out_str.empty()) {
470 if (header_name)
471 OutputString("\n" + std::string(header_name) + "\n");
472 OutputString(out_str);
473 }
474 }
440 475
441 void PrintRuntimeDeps(const Target* target) { 476 void PrintRuntimeDeps(const Target* target) {
442 bool display_blame = 477 bool display_blame =
443 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame); 478 base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
444 Label toolchain = target->label().GetToolchainLabel(); 479 Label toolchain = target->label().GetToolchainLabel();
445 480
446 const Target* previous_from = NULL; 481 const Target* previous_from = NULL;
447 for (const auto& pair : ComputeRuntimeDeps(target)) { 482 for (const auto& pair : ComputeRuntimeDeps(target)) {
448 if (display_blame) { 483 if (display_blame) {
449 // Generally a target's runtime deps will be listed sequentially, so 484 // 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. 485 // group them and don't duplicate the "from" label for two in a row.
451 if (previous_from == pair.second) { 486 if (previous_from == pair.second) {
452 OutputString(" "); // Just indent. 487 OutputString(" "); // Just indent.
453 } else { 488 } else {
454 previous_from = pair.second; 489 previous_from = pair.second;
455 OutputString("From "); 490 OutputString("From ");
456 OutputString(pair.second->label().GetUserVisibleName(toolchain)); 491 OutputString(pair.second->label().GetUserVisibleName(toolchain));
457 OutputString("\n "); // Make the file name indented. 492 OutputString("\n "); // Make the file name indented.
458 } 493 }
459 } 494 }
460 OutputString(pair.first.value()); 495 OutputString(pair.first.value());
461 OutputString("\n"); 496 OutputString("\n");
462 } 497 }
463 } 498 }
464 499
500 // If "what" is empty, prints all PCH info. If "what" is nonempty, prints only
501 // the things that match (if any). Returns true if anything was printed.
502 bool PrintPrecompiledHeaderInfo(const ConfigValues& values,
503 const std::string& what,
504 bool display_headers) {
505 bool found_match = false;
506 if (what == variables::kPrecompiledHeader || what.empty()) {
507 if (!values.precompiled_header().empty()) {
508 if (display_headers)
509 OutputString("\nprecompiled_header\n");
510 OutputString(values.precompiled_header() + "\n");
511 }
512 found_match = true;
513 }
514 if (what == variables::kPrecompiledSource || what.empty()) {
515 if (!values.precompiled_source().is_null()) {
516 if (display_headers)
517 OutputString("\nprecompiled_source\n");
518 OutputString(values.precompiled_source().value() + "\n");
519 }
520 found_match = true;
521 }
522 return found_match;
523 }
524
525 bool PrintTarget(const Target* target,
526 const std::string& what,
527 bool display_target_header) {
528 if (display_target_header) {
529 OutputString("Target: ", DECORATION_YELLOW);
530 OutputString(target->label().GetUserVisibleName(false) + "\n");
531 OutputString("Type: ", DECORATION_YELLOW);
532 OutputString(std::string(
533 Target::GetStringForOutputType(target->output_type())) + "\n");
534 OutputString("Toolchain: ", DECORATION_YELLOW);
535 OutputString(
536 target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
537 }
538
539 // Display headers when outputting everything.
540 bool display_headers = what.empty();
541 bool is_binary_output = target->IsBinary();
542
543 bool found_match = false;
544
545 // General target meta variables.
546 if (what.empty() || what == variables::kVisibility) {
547 PrintVisibility(target, display_headers);
548 found_match = true;
549 }
550 if (what.empty() || what == variables::kTestonly) {
551 PrintTestonly(target, display_headers);
552 found_match = true;
553 }
554
555 // Binary target meta variables.
556 if (is_binary_output) {
557 if (what.empty() || what == variables::kCheckIncludes) {
558 PrintCheckIncludes(target, display_headers);
559 found_match = true;
560 }
561 if (what.empty() || what == variables::kAllowCircularIncludesFrom) {
562 PrintAllowCircularIncludesFrom(target, display_headers);
563 found_match = true;
564 }
565 }
566
567 // Sources and inputs.
568 if (what.empty() || what == variables::kSources) {
569 PrintSources(target, display_headers);
570 found_match = true;
571 }
572 if (what.empty() || what == variables::kPublic) {
573 PrintPublic(target, display_headers);
574 found_match = true;
575 }
576 if (what.empty() || what == variables::kInputs) {
577 PrintInputs(target, display_headers);
578 found_match = true;
579 }
580
581 // Configs. Configs set directly on a target are only relevant for binary
582 // targets
583 if (is_binary_output && (what.empty() || what == variables::kConfigs)) {
584 PrintConfigs(target, display_headers);
585 found_match = true;
586 }
587
588 // Dependent/public configs can be applied to anything.
589 if (what.empty() || what == variables::kPublicConfigs) {
590 PrintPublicConfigs(target, display_headers);
591 found_match = true;
592 }
593 if (what.empty() || what == variables::kAllDependentConfigs) {
594 PrintAllDependentConfigs(target, display_headers);
595 found_match = true;
596 }
597
598 // Action values.
599 if (target->output_type() == Target::ACTION ||
600 target->output_type() == Target::ACTION_FOREACH) {
601 if (what.empty() || what == variables::kScript) {
602 PrintScript(target, display_headers);
603 found_match = true;
604 }
605 if (what.empty() || what == variables::kArgs) {
606 PrintArgs(target, display_headers);
607 found_match = true;
608 }
609 if (what.empty() || what == variables::kDepfile) {
610 PrintDepfile(target, display_headers);
611 found_match = true;
612 }
613 }
614
615 // Outputs.
616 if (target->output_type() == Target::ACTION ||
617 target->output_type() == Target::ACTION_FOREACH ||
618 target->output_type() == Target::COPY_FILES ||
619 target->output_type() == Target::CREATE_BUNDLE) {
620 if (what.empty() || what == variables::kOutputs) {
621 PrintOutputs(target, display_headers);
622 found_match = true;
623 }
624 }
625
626 // Values from configs only apply to binary targets.
627 if (is_binary_output) {
628 #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
629 if (what.empty() || what == #name) { \
630 OutputRecursiveTargetConfig<type>( \
631 target, display_headers ? #name : nullptr, &ConfigValues::name); \
632 found_match = true; \
633 }
634
635 CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
636 CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
637 CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
638 CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
639 CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
640 CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
641 CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
642 CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
643 CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
644 CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
645 // Libs and lib_dirs are handled specially below.
646
647 #undef CONFIG_VALUE_ARRAY_HANDLER
648
649 found_match |= PrintPrecompiledHeaderInfo(target->config_values(),
650 what, display_headers);
651 }
652
653 // Deps
654 if (what.empty() || what == "deps") {
655 PrintDeps(target, display_headers);
656 found_match = true;
657 }
658
659 // Runtime deps are special, print only when explicitly asked for and not in
660 // overview mode.
661 if (what == "runtime_deps") {
662 PrintRuntimeDeps(target);
663 found_match = true;
664 }
665
666 // Libs can be part of any target and get recursively pushed up the chain,
667 // so display them regardless of target type.
668 if (what.empty() || what == variables::kLibs) {
669 PrintLibs(target, display_headers);
670 found_match = true;
671 }
672 if (what.empty() || what == variables::kLibDirs) {
673 PrintLibDirs(target, display_headers);
674 found_match = true;
675 }
676
677 if (!found_match) {
678 OutputString("Don't know how to display \"" + what + "\" for \"" +
679 Target::GetStringForOutputType(target->output_type()) + "\".\n");
680 return false;
681 }
682 return true;
683 }
684
685 bool PrintConfig(const Config* config,
686 const std::string& what,
687 bool display_config_header) {
688 const ConfigValues& values = config->resolved_values();
689
690 if (display_config_header) {
691 OutputString("Config: ", DECORATION_YELLOW);
692 OutputString(config->label().GetUserVisibleName(false) + "\n");
693 OutputString("Toolchain: ", DECORATION_YELLOW);
694 OutputString(
695 config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
696 if (what.empty() && !config->configs().empty()) {
697 OutputString(
698 "(This is a composite config, the values below are after the\n"
699 "expansion of the child configs.)\n");
700 }
701 }
702
703 // Display headers when outputting everything.
704 bool display_headers = what.empty();
705
706 if (what.empty() || what == variables::kConfigs)
707 PrintConfigs(config, display_headers);
708
709 #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
710 if (what.empty() || what == #name) { \
711 OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \
712 &ConfigValues::name); \
713 found_match = true; \
714 }
715
716 bool found_match = false;
717
718 CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
719 CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
720 CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
721 CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
722 CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
723 CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
724 CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
725 CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
726 CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
727 CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
728 CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir)
729 CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile)
730
731 #undef CONFIG_VALUE_ARRAY_HANDLER
732
733 // Handles all PCH-related variables.
734 found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(),
735 what, display_headers);
736
737 if (!found_match) {
738 OutputString("Don't know how to display \"" + what + "\" for a config.\n");
739 return false;
740 }
741 return true;
742 }
743
465 } // namespace 744 } // namespace
466 745
467 // desc ------------------------------------------------------------------------ 746 // desc ------------------------------------------------------------------------
468 747
469 const char kDesc[] = "desc"; 748 const char kDesc[] = "desc";
470 const char kDesc_HelpShort[] = 749 const char kDesc_HelpShort[] =
471 "desc: Show lots of insightful information about a target."; 750 "desc: Show lots of insightful information about a target or config.";
472 const char kDesc_Help[] = 751 const char kDesc_Help[] =
473 "gn desc <out_dir> <target label> [<what to show>] [--blame]\n" 752 "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n"
474 "\n" 753 "\n"
475 " Displays information about a given labeled target for the given build.\n" 754 " 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" 755 " build parameters will be taken for the build in the given <out_dir>.\n"
477 " <out_dir>.\n" 756 "\n"
757 " The <label or pattern> can be a target label, a config label, or a\n"
758 " label pattern (see \"gn help label_pattern\"). A label pattern will\n"
759 " only match targets.\n"
478 "\n" 760 "\n"
479 "Possibilities for <what to show>\n" 761 "Possibilities for <what to show>\n"
762 "\n"
480 " (If unspecified an overall summary will be displayed.)\n" 763 " (If unspecified an overall summary will be displayed.)\n"
481 "\n" 764 "\n"
482 " sources\n" 765 " all_dependent_configs\n"
483 " Source files.\n" 766 " allow_circular_includes_from\n"
484 "\n" 767 " arflags [--blame]\n"
768 " args\n"
769 " cflags [--blame]\n"
770 " cflags_cc [--blame]\n"
771 " cflags_cxx [--blame]\n"
772 " check_includes\n"
773 " configs [--tree] (see below)\n"
774 " defines [--blame]\n"
775 " depfile\n"
776 " deps [--all] [--tree] (see below)\n"
777 " include_dirs [--blame]\n"
485 " inputs\n" 778 " inputs\n"
486 " Additional input dependencies.\n" 779 " 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" 780 " lib_dirs\n"
535 " libs\n" 781 " libs\n"
536 " Shows the given values taken from the target and all configs\n" 782 " outputs\n"
537 " applying. See \"--blame\" below.\n" 783 " public_configs\n"
784 " public\n"
785 " script\n"
786 " sources\n"
787 " testonly\n"
788 " visibility\n"
538 "\n" 789 "\n"
539 " runtime_deps\n" 790 " runtime_deps\n"
540 " Compute all runtime deps for the given target. This is a\n" 791 " 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" 792 " computed list and does not correspond to any GN variable, unlike\n"
542 " most other values here.\n" 793 " most other values here.\n"
543 "\n" 794 "\n"
544 " The output is a list of file names relative to the build\n" 795 " 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" 796 " 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" 797 " This also works with \"--blame\" to see the source of the\n"
547 " dependency.\n" 798 " dependency.\n"
548 "\n" 799 "\n"
549 "Shared flags\n" 800 "Shared flags\n"
550 "\n" 801 "\n"
802 ALL_TOOLCHAINS_SWITCH_HELP
803 "\n"
804 "Target flags\n"
805 "\n"
551 " --blame\n" 806 " --blame\n"
552 " Used with any value specified by a config, this will name\n" 807 " 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" 808 " 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" 809 " currently work for libs and lib_dirs because those are inherited\n"
555 " complicated to figure out the blame (patches welcome).\n" 810 " and are more complicated to figure out the blame (patches\n"
811 " welcome).\n"
556 "\n" 812 "\n"
557 "Flags that control how deps are printed\n" 813 "Configs\n"
814 "\n"
815 " The \"configs\" section will list all configs that apply. For targets\n"
816 " this will include configs specified in the \"configs\" variable of\n"
817 " the target, and also configs pushed onto this target via public\n"
818 " or \"all dependent\" configs.\n"
819 "\n"
820 " Configs can have child configs. Specifying --tree will show the\n"
821 " hierarchy.\n"
822 "\n"
823 "Printing deps\n"
824 "\n"
825 " Deps will include all public, private, and data deps (TODO this could\n"
826 " be clarified and enhanced) sorted in order applying. The following\n"
827 " may be used:\n"
558 "\n" 828 "\n"
559 " --all\n" 829 " --all\n"
560 " Collects all recursive dependencies and prints a sorted flat list.\n" 830 " Collects all recursive dependencies and prints a sorted flat list.\n"
561 " Also usable with --tree (see below).\n" 831 " Also usable with --tree (see below).\n"
562 "\n" 832 "\n"
563 TARGET_PRINTING_MODE_COMMAND_LINE_HELP 833 TARGET_PRINTING_MODE_COMMAND_LINE_HELP
564 "\n" 834 "\n"
565 TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP 835 TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP
566 "\n" 836 "\n"
567 " --tree\n" 837 " --tree\n"
(...skipping 23 matching lines...) Expand all
591 " Summarizes the given target.\n" 861 " Summarizes the given target.\n"
592 "\n" 862 "\n"
593 " gn desc out/Foo :base_unittests deps --tree\n" 863 " gn desc out/Foo :base_unittests deps --tree\n"
594 " Shows a dependency tree of the \"base_unittests\" project in\n" 864 " Shows a dependency tree of the \"base_unittests\" project in\n"
595 " the current directory.\n" 865 " the current directory.\n"
596 "\n" 866 "\n"
597 " gn desc out/Debug //base defines --blame\n" 867 " gn desc out/Debug //base defines --blame\n"
598 " Shows defines set for the //base:base target, annotated by where\n" 868 " Shows defines set for the //base:base target, annotated by where\n"
599 " each one was set from.\n"; 869 " each one was set from.\n";
600 870
601 #define OUTPUT_CONFIG_VALUE(name, type) \
602 OutputRecursiveTargetConfig<type>(target, #name, &ConfigValues::name);
603
604 int RunDesc(const std::vector<std::string>& args) { 871 int RunDesc(const std::vector<std::string>& args) {
605 if (args.size() != 2 && args.size() != 3) { 872 if (args.size() != 2 && args.size() != 3) {
606 Err(Location(), "You're holding it wrong.", 873 Err(Location(), "You're holding it wrong.",
607 "Usage: \"gn desc <out_dir> <target_name> [<what to display>]\"") 874 "Usage: \"gn desc <out_dir> <target_name> [<what to display>]\"")
608 .PrintToStdout(); 875 .PrintToStdout();
609 return 1; 876 return 1;
610 } 877 }
878 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
611 879
612 // Deliberately leaked to avoid expensive process teardown. 880 // Deliberately leaked to avoid expensive process teardown.
613 Setup* setup = new Setup; 881 Setup* setup = new Setup;
614 setup->build_settings().set_check_for_bad_items(false); 882 setup->build_settings().set_check_for_bad_items(false);
615 if (!setup->DoSetup(args[0], false)) 883 if (!setup->DoSetup(args[0], false))
616 return 1; 884 return 1;
617 if (!setup->Run()) 885 if (!setup->Run())
618 return 1; 886 return 1;
619 887
620 const Target* target = ResolveTargetFromCommandLineString(setup, args[1]); 888 // Resolve target(s) and config from inputs.
621 if (!target) 889 UniqueVector<const Target*> target_matches;
890 UniqueVector<const Config*> config_matches;
891 UniqueVector<const Toolchain*> toolchain_matches;
892 UniqueVector<SourceFile> file_matches;
893
894 std::vector<std::string> target_list;
895 target_list.push_back(args[1]);
896
897 if (!ResolveFromCommandLineInput(
898 setup, target_list, cmdline->HasSwitch(switches::kAllToolchains),
899 &target_matches, &config_matches, &toolchain_matches, &file_matches))
622 return 1; 900 return 1;
623 901
624 #define CONFIG_VALUE_HANDLER(name, type) \ 902 std::string what_to_print;
625 } else if (what == #name) { OUTPUT_CONFIG_VALUE(name, type) 903 if (args.size() == 3)
904 what_to_print = args[2];
626 905
627 if (args.size() == 3) { 906 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 907
668 CONFIG_VALUE_HANDLER(defines, std::string) 908 // Display headers for each target when printing all values, or when printing
669 CONFIG_VALUE_HANDLER(include_dirs, SourceDir) 909 // multiple targets or configs.
670 CONFIG_VALUE_HANDLER(arflags, std::string) 910 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 911
679 } else { 912 bool printed_output = false;
680 OutputString("Don't know how to display \"" + what + "\".\n"); 913 for (const Target* target : target_matches) {
914 if (printed_output)
915 OutputString("\n\n");
916 printed_output = true;
917
918 if (!PrintTarget(target, what_to_print, display_item_header))
681 return 1; 919 return 1;
682 } 920 }
921 for (const Config* config : config_matches) {
922 if (printed_output)
923 OutputString("\n\n");
924 printed_output = true;
683 925
684 #undef CONFIG_VALUE_HANDLER 926 if (!PrintConfig(config, what_to_print, display_item_header))
685 return 0; 927 return 1;
686 } 928 }
687 929
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; 930 return 0;
768 } 931 }
769 932
770 } // namespace commands 933 } // namespace commands
OLDNEW
« no previous file with comments | « no previous file | tools/gn/command_ls.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698