Chromium Code Reviews| Index: tools/gn/command_desc.cc |
| diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc |
| index 021232c1243c139f7e643d0d02a63f7ee04dd4eb..b315fa08914b00d2f08cb9690e9f84db445f2812 100644 |
| --- a/tools/gn/command_desc.cc |
| +++ b/tools/gn/command_desc.cc |
| @@ -21,6 +21,7 @@ |
| #include "tools/gn/setup.h" |
| #include "tools/gn/standard_out.h" |
| #include "tools/gn/substitution_writer.h" |
| +#include "tools/gn/switches.h" |
| #include "tools/gn/target.h" |
| #include "tools/gn/variables.h" |
| @@ -119,7 +120,7 @@ void PrintDeps(const Target* target, bool display_header) { |
| // Tree mode is separate. |
| if (cmdline->HasSwitch(kTree)) { |
| if (display_header) |
| - OutputString("\nDependency tree:\n"); |
| + OutputString("\nDependency tree\n"); |
| if (cmdline->HasSwitch("all")) { |
| // Show all tree deps with no eliding. |
| @@ -136,7 +137,7 @@ void PrintDeps(const Target* target, bool display_header) { |
| if (cmdline->HasSwitch("all")) { |
| // Show all dependencies. |
| if (display_header) |
| - OutputString("\nAll recursive dependencies:\n"); |
| + OutputString("\nAll recursive dependencies\n"); |
| std::set<const Target*> all_deps; |
| RecursiveCollectChildDeps(target, &all_deps); |
| @@ -147,7 +148,7 @@ void PrintDeps(const Target* target, bool display_header) { |
| if (display_header) { |
| OutputString( |
| "\nDirect dependencies " |
| - "(try also \"--all\", \"--tree\", or even \"--all --tree\"):\n"); |
| + "(try also \"--all\", \"--tree\", or even \"--all --tree\")\n"); |
| } |
| for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) |
| deps.push_back(pair.ptr); |
| @@ -185,7 +186,7 @@ void PrintLibs(const Target* target, bool display_header) { |
| void PrintPublic(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\npublic:\n"); |
| + OutputString("\npublic\n"); |
| if (target->all_headers_public()) { |
| OutputString(" [All headers listed in the sources are public.]\n"); |
| @@ -200,7 +201,7 @@ void PrintPublic(const Target* target, bool display_header) { |
| void PrintCheckIncludes(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\ncheck_includes:\n"); |
| + OutputString("\ncheck_includes\n"); |
| if (target->check_includes()) |
| OutputString(" true\n"); |
| @@ -210,7 +211,7 @@ void PrintCheckIncludes(const Target* target, bool display_header) { |
| void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\nallow_circular_includes_from:\n"); |
| + OutputString("\nallow_circular_includes_from\n"); |
| Label toolchain_label = target->label().GetToolchainLabel(); |
| for (const auto& cur : target->allow_circular_includes_from()) |
| @@ -219,14 +220,14 @@ void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) { |
| void PrintVisibility(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\nvisibility:\n"); |
| + OutputString("\nvisibility\n"); |
| OutputString(target->visibility().Describe(2, false)); |
| } |
| void PrintTestonly(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\ntestonly:\n"); |
| + OutputString("\ntestonly\n"); |
| if (target->testonly()) |
| OutputString(" true\n"); |
| @@ -251,7 +252,7 @@ void PrintSubConfigs(const Config* config, int indent_level) { |
| // This allows configs stored as either std::vector<LabelConfigPair> or |
| // UniqueVector<LabelConfigPair> to be printed. |
| template <class VectorType> |
| -void PrintConfigsVector(const Target* target, |
| +void PrintConfigsVector(const Item* item, |
| const VectorType& configs, |
| const std::string& heading, |
| bool display_header) { |
| @@ -263,12 +264,12 @@ void PrintConfigsVector(const Target* target, |
| // Don't sort since the order determines how things are processed. |
| if (display_header) { |
| if (tree) |
| - OutputString("\n" + heading + " tree (in order applying):\n"); |
| + OutputString("\n" + heading + " tree (in order applying)\n"); |
| else |
| - OutputString("\n" + heading + " (in order applying, try also --tree):\n"); |
| + OutputString("\n" + heading + " (in order applying, try also --tree)\n"); |
| } |
| - Label toolchain_label = target->label().GetToolchainLabel(); |
| + Label toolchain_label = item->label().GetToolchainLabel(); |
| for (const auto& config : configs) { |
| OutputString(" " + config.label.GetUserVisibleName(toolchain_label) + |
| "\n"); |
| @@ -282,6 +283,11 @@ void PrintConfigs(const Target* target, bool display_header) { |
| display_header); |
| } |
| +void PrintConfigs(const Config* config, bool display_header) { |
| + PrintConfigsVector(config, config->configs().vector(), "configs", |
| + display_header); |
| +} |
| + |
| void PrintPublicConfigs(const Target* target, bool display_header) { |
| PrintConfigsVector(target, target->public_configs(), |
| "public_configs", display_header); |
| @@ -300,7 +306,7 @@ void PrintFileList(const Target::FileList& files, |
| return; |
| if (display_header) |
| - OutputString("\n" + header + ":\n"); |
| + OutputString("\n" + header + "\n"); |
| std::string indent = indent_extra ? " " : " "; |
| @@ -320,7 +326,7 @@ void PrintInputs(const Target* target, bool display_header) { |
| void PrintOutputs(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\noutputs:\n"); |
| + OutputString("\noutputs\n"); |
| if (target->output_type() == Target::ACTION) { |
| // Action, print out outputs, don't apply sources to it. |
| @@ -337,12 +343,12 @@ void PrintOutputs(const Target* target, bool display_header) { |
| if (!outputs.required_types().empty()) { |
| // Display the pattern and resolved pattern separately, since there are |
| // subtitutions used. |
| - OutputString(" Output pattern:\n"); |
| + OutputString(" Output pattern\n"); |
| for (const auto& elem : outputs.list()) |
| OutputString(" " + elem.AsString() + "\n"); |
| // Now display what that resolves to given the sources. |
| - OutputString("\n Resolved output file list:\n"); |
| + OutputString("\n Resolved output file list\n"); |
| } |
| // Resolved output list. |
| @@ -355,13 +361,13 @@ void PrintOutputs(const Target* target, bool display_header) { |
| void PrintScript(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\nscript:\n"); |
| + OutputString("\nscript\n"); |
| OutputString(" " + target->action_values().script().value() + "\n"); |
| } |
| void PrintArgs(const Target* target, bool display_header) { |
| if (display_header) |
| - OutputString("\nargs:\n"); |
| + OutputString("\nargs\n"); |
| for (const auto& elem : target->action_values().args().list()) { |
| OutputString(" " + elem.AsString() + "\n"); |
| } |
| @@ -371,7 +377,7 @@ void PrintDepfile(const Target* target, bool display_header) { |
| if (target->action_values().depfile().empty()) |
| return; |
| if (display_header) |
| - OutputString("\ndepfile:\n"); |
| + OutputString("\ndepfile\n"); |
| OutputString(" " + target->action_values().depfile().AsString() + "\n"); |
| } |
| @@ -397,6 +403,14 @@ template<> struct DescValueWriter<SourceDir> { |
| out << " " << FormatSourceDir(dir) << "\n"; |
| } |
| }; |
| +template<> struct DescValueWriter<LibFile> { |
|
scottmg
2016/05/10 17:40:55
\n before
|
| + void operator()(const LibFile& lib, std::ostream& out) const { |
| + if (lib.is_source_file()) |
| + out << " " << lib.source_file().value() << "\n"; |
| + else |
| + out << " " << lib.value() << "\n"; |
| + } |
| +}; |
| // Writes a given config value type to the string, optionally with attribution. |
| // This should match RecursiveTargetConfigToStream in the order it traverses. |
| @@ -433,7 +447,26 @@ template<typename T> void OutputRecursiveTargetConfig( |
| std::string out_str = out.str(); |
| if (!out_str.empty()) { |
| - OutputString("\n" + std::string(header_name) + "\n"); |
| + if (header_name) |
| + OutputString("\n" + std::string(header_name) + "\n"); |
| + OutputString(out_str); |
| + } |
| +} |
| + |
| +template<typename T> void OutputConfigValueArray( |
| + const ConfigValues& values, |
| + const char* header_name, |
| + const std::vector<T>& (ConfigValues::* getter)() const) { |
| + std::ostringstream out; |
| + |
| + DescValueWriter<T> writer; |
| + for (const T& cur : (values.*getter)()) |
| + writer(cur, out); |
| + |
| + std::string out_str = out.str(); |
| + if (!out_str.empty()) { |
| + if (header_name) |
| + OutputString("\n" + std::string(header_name) + "\n"); |
| OutputString(out_str); |
| } |
| } |
| @@ -462,79 +495,303 @@ void PrintRuntimeDeps(const Target* target) { |
| } |
| } |
| +// If "what" is empty, prints all PCH info. If "what" is nonempty, prints only |
| +// the things that match (if any). Returns true if anything was printed. |
| +bool PrintPrecompiledHeaderInfo(const ConfigValues& values, |
| + const std::string& what, |
| + bool display_headers) { |
| + bool found_match = false; |
| + if (what == "precompiled_header" || what.empty()) { |
|
scottmg
2016/05/10 17:40:55
-> kPrecompiledHeader
You have all the what.empty
|
| + if (!values.precompiled_header().empty()) { |
| + if (display_headers) |
| + OutputString("\nprecompiled_header\n"); |
| + OutputString(values.precompiled_header() + "\n"); |
| + } |
| + found_match = true; |
| + } |
| + if (what == "precompiled_source" || what.empty()) { |
|
scottmg
2016/05/10 17:40:55
same kPrecompiledSource
|
| + if (!values.precompiled_source().is_null()) { |
| + if (display_headers) |
| + OutputString("\nprecompiled_source\n"); |
| + OutputString(values.precompiled_source().value() + "\n"); |
| + } |
| + found_match = true; |
| + } |
| + return found_match; |
| +} |
| + |
| +bool PrintTarget(const Target* target, |
| + const std::string& what, |
| + bool display_target_header) { |
| + if (display_target_header) { |
| + OutputString("Target: ", DECORATION_YELLOW); |
| + OutputString(target->label().GetUserVisibleName(false) + "\n"); |
| + OutputString("Type: ", DECORATION_YELLOW); |
| + OutputString(std::string( |
| + Target::GetStringForOutputType(target->output_type())) + "\n"); |
| + OutputString("Toolchain: ", DECORATION_YELLOW); |
| + OutputString( |
| + target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); |
| + } |
| + |
| + // Display headers when outputting everything. |
| + bool display_headers = what.empty(); |
| + |
| + bool found_match = false; |
| + |
| + // Display this only applicable to binary targets. |
| + bool is_binary_output = |
|
scottmg
2016/05/10 17:40:55
Is this Target::IsBinary()? (other than UNKNOWN.)
|
| + target->output_type() != Target::GROUP && |
| + target->output_type() != Target::COPY_FILES && |
| + target->output_type() != Target::ACTION && |
| + target->output_type() != Target::ACTION_FOREACH && |
| + target->output_type() != Target::BUNDLE_DATA && |
| + target->output_type() != Target::CREATE_BUNDLE; |
| + |
| + // General target meta variables. |
| + if (what.empty() || what == variables::kVisibility) { |
| + PrintVisibility(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kTestonly) { |
| + PrintTestonly(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + // Binary target meta variables. |
| + if (is_binary_output) { |
| + if (what.empty() || what == variables::kCheckIncludes) { |
| + PrintCheckIncludes(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kAllowCircularIncludesFrom) { |
| + PrintAllowCircularIncludesFrom(target, display_headers); |
| + found_match = true; |
| + } |
| + } |
| + |
| + // Sources and inputs. |
| + if (what.empty() || what == variables::kSources) { |
| + PrintSources(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kPublic) { |
| + PrintPublic(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kInputs) { |
| + PrintInputs(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + // Configs. Configs set directly on a target are only relevant for binary |
| + // targets |
| + if (is_binary_output && (what.empty() || what == variables::kConfigs)) { |
| + PrintConfigs(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + // Dependent/public configs can be applied to anything. |
| + if (what.empty() || what == variables::kPublicConfigs) { |
| + PrintPublicConfigs(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kAllDependentConfigs) { |
| + PrintAllDependentConfigs(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + // Action values. |
| + if (target->output_type() == Target::ACTION || |
| + target->output_type() == Target::ACTION_FOREACH) { |
| + if (what == variables::kScript) { |
|
scottmg
2016/05/10 17:40:55
`what.empty() ||` and for kArgs? If not, a comment
|
| + PrintScript(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what == variables::kArgs) { |
| + PrintArgs(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kDepfile) { |
| + PrintDepfile(target, display_headers); |
| + found_match = true; |
| + } |
| + } |
| + |
| + // Outputs. |
| + if (target->output_type() == Target::ACTION || |
| + target->output_type() == Target::ACTION_FOREACH || |
| + target->output_type() == Target::COPY_FILES || |
| + target->output_type() == Target::CREATE_BUNDLE) { |
| + if (what.empty() || what == variables::kOutputs) { |
| + PrintOutputs(target, display_headers); |
| + found_match = true; |
| + } |
| + } |
| + |
| + // Values from configs only apply to binary targets. |
| + if (is_binary_output) { |
| + #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ |
| + if (what.empty() || what == #name) { \ |
| + OutputRecursiveTargetConfig<type>( \ |
| + target, display_headers ? #name : nullptr, &ConfigValues::name); \ |
| + found_match = true; \ |
| + } |
| + |
| + CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) |
| + CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) |
| + // Libs and lib_dirs are handled specially below. |
| + |
| + #undef CONFIG_VALUE_ARRAY_HANDLER |
| + |
| + found_match |= PrintPrecompiledHeaderInfo(target->config_values(), |
| + what, display_headers); |
| + } |
| + |
| + // Deps |
| + if (what.empty() || what == "deps") { |
| + PrintDeps(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + // Runtime deps are special, print only when explicitly asked for and not in |
| + // overview mode. |
| + if (what == "runtime_deps") { |
| + PrintRuntimeDeps(target); |
| + found_match = true; |
| + } |
| + |
| + // Libs can be part of any target and get recursively pushed up the chain, |
| + // so display them regardless of target type. |
| + if (what.empty() || what == variables::kLibs) { |
| + PrintLibs(target, display_headers); |
| + found_match = true; |
| + } |
| + if (what.empty() || what == variables::kLibDirs) { |
| + PrintLibDirs(target, display_headers); |
| + found_match = true; |
| + } |
| + |
| + if (!found_match) { |
| + OutputString("Don't know how to display \"" + what + "\" for \"" + |
| + Target::GetStringForOutputType(target->output_type()) + "\".\n"); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +bool PrintConfig(const Config* config, |
| + const std::string& what, |
| + bool display_config_header) { |
| + const ConfigValues& values = config->resolved_values(); |
| + |
| + if (display_config_header) { |
| + OutputString("Config: ", DECORATION_YELLOW); |
| + OutputString(config->label().GetUserVisibleName(false) + "\n"); |
| + OutputString("Toolchain: ", DECORATION_YELLOW); |
| + OutputString( |
| + config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n"); |
| + if (what.empty() && !config->configs().empty()) { |
| + OutputString( |
| + "(This is a composite config, the values below are after the\n" |
| + "expansion of the child configs.)\n"); |
| + } |
| + } |
| + |
| + // Display headers when outputting everything. |
| + bool display_headers = what.empty(); |
| + |
| + if (what.empty() || what == variables::kConfigs) |
| + PrintConfigs(config, display_headers); |
| + |
| +#define CONFIG_VALUE_ARRAY_HANDLER(name, type) \ |
| + if (what.empty() || what == #name) { \ |
| + OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \ |
| + &ConfigValues::name); \ |
| + found_match = true; \ |
| + } |
| + |
| + bool found_match = false; |
| + |
| + CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(defines, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir) |
| + CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string) |
| + CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir) |
| + CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile) |
| + |
| +#undef CONFIG_VALUE_ARRAY_HANDLER |
| + |
| + // Handles all PCH-related variables. |
| + found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(), |
| + what, display_headers); |
| + |
| + if (!found_match) { |
| + OutputString("Don't know how to display \"" + what + "\" for a config.\n"); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| } // namespace |
| // desc ------------------------------------------------------------------------ |
| const char kDesc[] = "desc"; |
| const char kDesc_HelpShort[] = |
| - "desc: Show lots of insightful information about a target."; |
| + "desc: Show lots of insightful information about a target or config."; |
| const char kDesc_Help[] = |
| - "gn desc <out_dir> <target label> [<what to show>] [--blame]\n" |
| + "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n" |
| "\n" |
| - " Displays information about a given labeled target for the given build.\n" |
| - " The build parameters will be taken for the build in the given\n" |
| - " <out_dir>.\n" |
| + " Displays information about a given target or config. The build\n" |
| + " build parameters will be taken for the build in the given <out_dir>.\n" |
| "\n" |
| - "Possibilities for <what to show>\n" |
| - " (If unspecified an overall summary will be displayed.)\n" |
| - "\n" |
| - " sources\n" |
| - " Source files.\n" |
| - "\n" |
| - " inputs\n" |
| - " Additional input dependencies.\n" |
| - "\n" |
| - " public\n" |
| - " Public header files.\n" |
| - "\n" |
| - " check_includes\n" |
| - " Whether \"gn check\" checks this target for include usage.\n" |
| + " The <label or pattern> can be a target label, a config label, or a\n" |
| + " label pattern (see \"gn help label_pattern\"). A label pattern will\n" |
| + " only match targets.\n" |
| "\n" |
| - " allow_circular_includes_from\n" |
| - " Permit includes from these targets.\n" |
| - "\n" |
| - " visibility\n" |
| - " Prints which targets can depend on this one.\n" |
| - "\n" |
| - " testonly\n" |
| - " Whether this target may only be used in tests.\n" |
| - "\n" |
| - " configs\n" |
| - " Shows configs applied to the given target, sorted in the order\n" |
| - " they're specified. This includes both configs specified in the\n" |
| - " \"configs\" variable, as well as configs pushed onto this target\n" |
| - " via dependencies specifying \"all\" or \"direct\" dependent\n" |
| - " configs.\n" |
| + "Possibilities for <what to show>\n" |
| "\n" |
| - " deps\n" |
| - " Show immediate or recursive dependencies. See below for flags that\n" |
| - " control deps printing.\n" |
| + " (If unspecified an overall summary will be displayed.)\n" |
| "\n" |
| - " public_configs\n" |
| " all_dependent_configs\n" |
| - " Shows the labels of configs applied to targets that depend on this\n" |
| - " one (either directly or all of them).\n" |
| - "\n" |
| - " script\n" |
| + " allow_circular_includes_from\n" |
| + " arflags [--blame]\n" |
| " args\n" |
| + " cflags [--blame]\n" |
| + " cflags_cc [--blame]\n" |
| + " cflags_cxx [--blame]\n" |
| + " check_includes\n" |
| + " configs [--tree] (see below)\n" |
| + " defines [--blame]\n" |
| " depfile\n" |
| - " Actions only. The script and related values.\n" |
| - "\n" |
| - " outputs\n" |
| - " Outputs for script and copy target types.\n" |
| - "\n" |
| - " arflags [--blame]\n" |
| - " defines [--blame]\n" |
| - " include_dirs [--blame]\n" |
| - " cflags [--blame]\n" |
| - " cflags_cc [--blame]\n" |
| - " cflags_cxx [--blame]\n" |
| - " ldflags [--blame]\n" |
| + " deps [--all] [--tree] (see below)\n" |
| + " include_dirs [--blame]\n" |
| + " inputs\n" |
| + " ldflags [--blame]\n" |
| " lib_dirs\n" |
| " libs\n" |
| - " Shows the given values taken from the target and all configs\n" |
| - " applying. See \"--blame\" below.\n" |
| + " outputs\n" |
| + " public_configs\n" |
| + " public\n" |
| + " script\n" |
| + " sources\n" |
| + " testonly\n" |
| + " visibility\n" |
| "\n" |
| " runtime_deps\n" |
| " Compute all runtime deps for the given target. This is a\n" |
| @@ -548,13 +805,32 @@ const char kDesc_Help[] = |
| "\n" |
| "Shared flags\n" |
| "\n" |
| + ALL_TOOLCHAINS_SWITCH_HELP |
| + "\n" |
| + "Target flags\n" |
| + "\n" |
| " --blame\n" |
| - " Used with any value specified by a config, this will name\n" |
| - " the config that specified the value. This doesn't currently work\n" |
| - " for libs and lib_dirs because those are inherited and are more\n" |
| - " complicated to figure out the blame (patches welcome).\n" |
| + " Used with any value specified on a config, this will name\n" |
| + " the config that cause that target to get the flag. This doesn't\n" |
| + " currently work for libs and lib_dirs because those are inherited\n" |
| + " and are more complicated to figure out the blame (patches\n" |
| + " welcome).\n" |
| + "\n" |
| + "Configs\n" |
| + "\n" |
| + " The \"configs\" section will list all configs that apply. For targets\n" |
| + " this will include configs specified in the \"configs\" variable of\n" |
| + " the target, and also configs pushed onto this target via public\n" |
| + " or \"all dependent\" configs.\n" |
| + "\n" |
| + " Configs can have child configs. Specifying --tree will show the\n" |
| + " hierarchy.\n" |
| + "\n" |
| + "Printing deps\n" |
| "\n" |
| - "Flags that control how deps are printed\n" |
| + " Deps will include all public, private, and data deps (TODO this could\n" |
| + " be clarified and enhanced) sorted in order applying. The following\n" |
| + " may be used:\n" |
| "\n" |
| " --all\n" |
| " Collects all recursive dependencies and prints a sorted flat list.\n" |
| @@ -598,9 +874,6 @@ const char kDesc_Help[] = |
| " Shows defines set for the //base:base target, annotated by where\n" |
| " each one was set from.\n"; |
| -#define OUTPUT_CONFIG_VALUE(name, type) \ |
| - OutputRecursiveTargetConfig<type>(target, #name, &ConfigValues::name); |
| - |
| int RunDesc(const std::vector<std::string>& args) { |
| if (args.size() != 2 && args.size() != 3) { |
| Err(Location(), "You're holding it wrong.", |
| @@ -608,6 +881,7 @@ int RunDesc(const std::vector<std::string>& args) { |
| .PrintToStdout(); |
| return 1; |
| } |
| + const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); |
| // Deliberately leaked to avoid expensive process teardown. |
| Setup* setup = new Setup; |
| @@ -617,153 +891,48 @@ int RunDesc(const std::vector<std::string>& args) { |
| if (!setup->Run()) |
| return 1; |
| - const Target* target = ResolveTargetFromCommandLineString(setup, args[1]); |
| - if (!target) |
| - return 1; |
| - |
| -#define CONFIG_VALUE_HANDLER(name, type) \ |
| - } else if (what == #name) { OUTPUT_CONFIG_VALUE(name, type) |
| - |
| - if (args.size() == 3) { |
| - // User specified one thing to display. |
| - const std::string& what = args[2]; |
| - if (what == variables::kConfigs) { |
| - PrintConfigs(target, false); |
| - } else if (what == variables::kPublicConfigs) { |
| - PrintPublicConfigs(target, false); |
| - } else if (what == variables::kAllDependentConfigs) { |
| - PrintAllDependentConfigs(target, false); |
| - } else if (what == variables::kSources) { |
| - PrintSources(target, false); |
| - } else if (what == variables::kPublic) { |
| - PrintPublic(target, false); |
| - } else if (what == variables::kCheckIncludes) { |
| - PrintCheckIncludes(target, false); |
| - } else if (what == variables::kAllowCircularIncludesFrom) { |
| - PrintAllowCircularIncludesFrom(target, false); |
| - } else if (what == variables::kVisibility) { |
| - PrintVisibility(target, false); |
| - } else if (what == variables::kTestonly) { |
| - PrintTestonly(target, false); |
| - } else if (what == variables::kInputs) { |
| - PrintInputs(target, false); |
| - } else if (what == variables::kScript) { |
| - PrintScript(target, false); |
| - } else if (what == variables::kArgs) { |
| - PrintArgs(target, false); |
| - } else if (what == variables::kDepfile) { |
| - PrintDepfile(target, false); |
| - } else if (what == variables::kOutputs) { |
| - PrintOutputs(target, false); |
| - } else if (what == variables::kDeps) { |
| - PrintDeps(target, false); |
| - } else if (what == variables::kLibDirs) { |
| - PrintLibDirs(target, false); |
| - } else if (what == variables::kLibs) { |
| - PrintLibs(target, false); |
| - } else if (what == "runtime_deps") { |
| - PrintRuntimeDeps(target); |
| -// } Hidden closing brace in macro below. |
| - |
| - CONFIG_VALUE_HANDLER(defines, std::string) |
| - CONFIG_VALUE_HANDLER(include_dirs, SourceDir) |
| - CONFIG_VALUE_HANDLER(arflags, std::string) |
| - CONFIG_VALUE_HANDLER(asmflags, std::string) |
| - CONFIG_VALUE_HANDLER(cflags, std::string) |
| - CONFIG_VALUE_HANDLER(cflags_c, std::string) |
| - CONFIG_VALUE_HANDLER(cflags_cc, std::string) |
| - CONFIG_VALUE_HANDLER(cflags_objc, std::string) |
| - CONFIG_VALUE_HANDLER(cflags_objcc, std::string) |
| - CONFIG_VALUE_HANDLER(ldflags, std::string) |
| - |
| - } else { |
| - OutputString("Don't know how to display \"" + what + "\".\n"); |
| - return 1; |
| - } |
| - |
| -#undef CONFIG_VALUE_HANDLER |
| - return 0; |
| - } |
| + // Resolve target(s) and config from inputs. |
| + UniqueVector<const Target*> target_matches; |
| + UniqueVector<const Config*> config_matches; |
| + UniqueVector<const Toolchain*> toolchain_matches; |
| + UniqueVector<SourceFile> file_matches; |
| - // Display summary. |
| + std::vector<std::string> target_list; |
| + target_list.push_back(args[1]); |
| - // Display this only applicable to binary targets. |
| - bool is_binary_output = |
| - target->output_type() != Target::GROUP && |
| - target->output_type() != Target::COPY_FILES && |
| - target->output_type() != Target::ACTION && |
| - target->output_type() != Target::ACTION_FOREACH && |
| - target->output_type() != Target::BUNDLE_DATA && |
| - target->output_type() != Target::CREATE_BUNDLE; |
| - |
| - // Generally we only want to display toolchains on labels when the toolchain |
| - // is different than the default one for this target (which we always print |
| - // in the header). |
| - Label target_toolchain = target->label().GetToolchainLabel(); |
| - |
| - // Header. |
| - OutputString("Target: ", DECORATION_YELLOW); |
| - OutputString(target->label().GetUserVisibleName(false) + "\n"); |
| - OutputString("Type: ", DECORATION_YELLOW); |
| - OutputString(std::string( |
| - Target::GetStringForOutputType(target->output_type())) + "\n"); |
| - OutputString("Toolchain: ", DECORATION_YELLOW); |
| - OutputString(target_toolchain.GetUserVisibleName(false) + "\n"); |
| - |
| - PrintSources(target, true); |
| - if (is_binary_output) { |
| - PrintPublic(target, true); |
| - PrintCheckIncludes(target, true); |
| - PrintAllowCircularIncludesFrom(target, true); |
| - } |
| - PrintVisibility(target, true); |
| - if (is_binary_output) { |
| - PrintTestonly(target, true); |
| - PrintConfigs(target, true); |
| - } |
| + if (!ResolveFromCommandLineInput( |
| + setup, target_list, cmdline->HasSwitch(switches::kAllToolchains), |
| + &target_matches, &config_matches, &toolchain_matches, &file_matches)) |
| + return 1; |
| - PrintPublicConfigs(target, true); |
| - PrintAllDependentConfigs(target, true); |
| + std::string what_to_print; |
| + if (args.size() == 3) |
| + what_to_print = args[2]; |
| - PrintInputs(target, true); |
| + bool multiple_outputs = target_matches.size() + config_matches.size() > 1; |
|
scottmg
2016/05/10 17:40:55
I read this at first as X + (Y > 1), maybe put ()
|
| - if (is_binary_output) { |
| - OUTPUT_CONFIG_VALUE(defines, std::string) |
| - OUTPUT_CONFIG_VALUE(include_dirs, SourceDir) |
| - OUTPUT_CONFIG_VALUE(asmflags, std::string) |
| - OUTPUT_CONFIG_VALUE(cflags, std::string) |
| - OUTPUT_CONFIG_VALUE(cflags_c, std::string) |
| - OUTPUT_CONFIG_VALUE(cflags_cc, std::string) |
| - OUTPUT_CONFIG_VALUE(cflags_objc, std::string) |
| - OUTPUT_CONFIG_VALUE(cflags_objcc, std::string) |
| + // Display headers for each target when printing all values, or when printing |
| + // multiple targets or configs. |
| + bool display_item_header = multiple_outputs || what_to_print.empty(); |
| - if (target->output_type() == Target::STATIC_LIBRARY) |
| - OUTPUT_CONFIG_VALUE(arflags, std::string) |
| - else if (target->output_type() != Target::SOURCE_SET) |
| - OUTPUT_CONFIG_VALUE(ldflags, std::string) |
| - } |
| + bool printed_output = false; |
| + for (const Target* target : target_matches) { |
| + if (printed_output) |
| + OutputString("\n\n"); |
| + printed_output = true; |
| - if (target->output_type() == Target::ACTION || |
| - target->output_type() == Target::ACTION_FOREACH) { |
| - PrintScript(target, true); |
| - PrintArgs(target, true); |
| - PrintDepfile(target, true); |
| + if (!PrintTarget(target, what_to_print, display_item_header)) |
| + return 1; |
| } |
| + for (const Config* config : config_matches) { |
| + if (printed_output) |
| + OutputString("\n\n"); |
| + printed_output = true; |
| - if (target->output_type() == Target::ACTION || |
| - target->output_type() == Target::ACTION_FOREACH || |
| - target->output_type() == Target::COPY_FILES || |
| - target->output_type() == Target::CREATE_BUNDLE) { |
| - PrintOutputs(target, true); |
| + if (!PrintConfig(config, what_to_print, display_item_header)) |
| + return 1; |
| } |
| - // Libs can be part of any target and get recursively pushed up the chain, |
| - // so always display them, even for groups and such. |
| - PrintLibs(target, true); |
| - PrintLibDirs(target, true); |
| - |
| - PrintDeps(target, true); |
| - |
| return 0; |
| } |