Index: tools/gn/command_desc.cc |
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc |
index 021232c1243c139f7e643d0d02a63f7ee04dd4eb..f2371e9d7cb5a8591681819956cf39309e925b4f 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"); |
} |
@@ -392,12 +398,22 @@ template<> struct DescValueWriter<std::string> { |
out << " " << str << "\n"; |
} |
}; |
+ |
template<> struct DescValueWriter<SourceDir> { |
void operator()(const SourceDir& dir, std::ostream& out) const { |
out << " " << FormatSourceDir(dir) << "\n"; |
} |
}; |
+template<> struct DescValueWriter<LibFile> { |
+ 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. |
template<typename T> void OutputRecursiveTargetConfig( |
@@ -433,7 +449,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 +497,295 @@ 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 == variables::kPrecompiledHeader || what.empty()) { |
+ if (!values.precompiled_header().empty()) { |
+ if (display_headers) |
+ OutputString("\nprecompiled_header\n"); |
+ OutputString(values.precompiled_header() + "\n"); |
+ } |
+ found_match = true; |
+ } |
+ if (what == variables::kPrecompiledSource || what.empty()) { |
+ 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 is_binary_output = target->IsBinary(); |
+ |
+ bool found_match = false; |
+ |
+ // 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.empty() || what == variables::kScript) { |
+ PrintScript(target, display_headers); |
+ found_match = true; |
+ } |
+ if (what.empty() || 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" |
+ " 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" |
- " public\n" |
- " Public header files.\n" |
- "\n" |
- " check_includes\n" |
- " Whether \"gn check\" checks this target for include usage.\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 +799,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" |
- "Flags that control how deps are printed\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" |
+ " 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 +868,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 +875,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 +885,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; |
- } |
- |
- // Display summary. |
+ // 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 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; |
+ std::vector<std::string> target_list; |
+ target_list.push_back(args[1]); |
- // 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; |
- 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; |
} |