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

Unified Diff: tools/gn/function_toolchain.cc

Issue 2178173002: Allow GN toolchains to specify runtime deps outputs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/function_toolchain_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/function_toolchain.cc
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc
index 210cc2c84b45c092f1c57732d9df70d6b2b66689..3501ec128a064a7ed86e822970e4a4a5af859cac 100644
--- a/tools/gn/function_toolchain.cc
+++ b/tools/gn/function_toolchain.cc
@@ -47,7 +47,7 @@ bool ReadBool(Scope* scope,
bool ReadString(Scope* scope,
const char* var,
Tool* tool,
- void (Tool::*set)(const std::string&),
+ void (Tool::*set)(std::string),
Err* err) {
const Value* v = scope->GetValue(var, true);
if (!v)
@@ -64,9 +64,8 @@ bool ReadString(Scope* scope,
bool ReadLabel(Scope* scope,
const char* var,
Tool* tool,
- const ParseNode* origin,
const Label& current_toolchain,
- void (Tool::*set)(const LabelPtrPair<Pool>&),
+ void (Tool::*set)(LabelPtrPair<Pool>),
Err* err) {
const Value* v = scope->GetValue(var, true);
if (!v)
@@ -78,9 +77,9 @@ bool ReadLabel(Scope* scope,
return false;
LabelPtrPair<Pool> pair(label);
- pair.origin = origin;
+ pair.origin = tool->defined_from();
- (tool->*set)(pair);
+ (tool->*set)(std::move(pair));
return true;
}
@@ -105,7 +104,7 @@ bool ReadPattern(Scope* scope,
const char* name,
bool (*validate)(SubstitutionType),
Tool* tool,
- void (Tool::*set)(const SubstitutionPattern&),
+ void (Tool::*set)(SubstitutionPattern),
Err* err) {
const Value* value = scope->GetValue(name, true);
if (!value)
@@ -119,7 +118,31 @@ bool ReadPattern(Scope* scope,
if (!ValidateSubstitutionList(pattern.required_types(), validate, value, err))
return false;
- (tool->*set)(pattern);
+ (tool->*set)(std::move(pattern));
+ return true;
+}
+
+bool ReadPatternList(Scope* scope,
+ const char* name,
+ bool (*validate)(SubstitutionType),
+ Tool* tool,
+ void (Tool::*set)(SubstitutionList),
+ Err* err) {
+ const Value* value = scope->GetValue(name, true);
+ if (!value)
+ return true; // Not present is fine.
+ if (!value->VerifyTypeIs(Value::LIST, err))
+ return false;
+
+ SubstitutionList list;
+ if (!list.Parse(*value, err))
+ return false;
+
+ // Validate the right kinds of patterns are used.
+ if (!ValidateSubstitutionList(list.required_types(), validate, value, err))
+ return false;
+
+ (tool->*set)(std::move(list));
return true;
}
@@ -182,35 +205,6 @@ bool ReadDepsFormat(Scope* scope, Tool* tool, Err* err) {
return true;
}
-bool ReadOutputs(Scope* scope,
- const FunctionCallNode* tool_function,
- bool (*validate)(SubstitutionType),
- Tool* tool,
- Err* err) {
- const Value* value = scope->GetValue("outputs", true);
- if (!value) {
- *err = Err(tool_function, "\"outputs\" must be specified for this tool.");
- return false;
- }
-
- SubstitutionList list;
- if (!list.Parse(*value, err))
- return false;
-
- // Validate the right kinds of patterns are used.
- if (!ValidateSubstitutionList(list.required_types(), validate, value, err))
- return false;
-
- // There should always be at least one output.
- if (list.list().empty()) {
- *err = Err(*value, "Outputs list is empty.", "I need some outputs.");
- return false;
- }
-
- tool->set_outputs(list);
- return true;
-}
-
bool IsCompilerTool(Toolchain::ToolType type) {
return type == Toolchain::TYPE_CC ||
type == Toolchain::TYPE_CXX ||
@@ -238,6 +232,68 @@ bool IsPatternInOutputList(const SubstitutionList& output_list,
return false;
}
+
+bool ValidateOutputs(const Tool* tool, Err* err) {
+ if (tool->outputs().list().empty()) {
+ *err = Err(tool->defined_from(),
+ "\"outputs\" must be specified for this tool.");
+ return false;
+ }
+ return true;
+}
+
+// Validates either link_output or depend_output. To generalize to either, pass
+// the associated pattern, and the variable name that should appear in error
+// messages.
+bool ValidateLinkAndDependOutput(const Tool* tool,
+ Toolchain::ToolType tool_type,
+ const SubstitutionPattern& pattern,
+ const char* variable_name,
+ Err* err) {
+ if (pattern.empty())
+ return true; // Empty is always OK.
+
+ // It should only be specified for certain tool types.
+ if (tool_type != Toolchain::TYPE_SOLINK &&
+ tool_type != Toolchain::TYPE_SOLINK_MODULE) {
+ *err = Err(tool->defined_from(),
+ "This tool specifies a " + std::string(variable_name) + ".",
+ "This is only valid for solink and solink_module tools.");
+ return false;
+ }
+
+ if (!IsPatternInOutputList(tool->outputs(), pattern)) {
+ *err = Err(tool->defined_from(), "This tool's link_output is bad.",
+ "It must match one of the outputs.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRuntimeOutputs(const Tool* tool,
+ Toolchain::ToolType tool_type,
+ Err* err) {
+ if (tool->runtime_outputs().list().empty())
+ return true; // Empty is always OK.
+
+ if (!IsLinkerTool(tool_type)) {
+ *err = Err(tool->defined_from(), "This tool specifies runtime_outputs.",
+ "This is only valid for linker tools (alink doesn't count).");
+ return false;
+ }
+
+ for (const SubstitutionPattern& pattern : tool->runtime_outputs().list()) {
+ if (!IsPatternInOutputList(tool->outputs(), pattern)) {
+ *err = Err(tool->defined_from(), "This tool's runtime_outputs is bad.",
+ "It must be a subset of the outputs. The bad one is:\n " +
+ pattern.AsString());
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace
// toolchain -------------------------------------------------------------------
@@ -527,9 +583,7 @@ const char kTool_Help[] =
"\n"
" If you specify more than one output for shared library links,\n"
" you should consider setting link_output, depend_output, and\n"
- " runtime_link_output. Otherwise, the first entry in the\n"
- " outputs list should always be the main output which will be\n"
- " linked to.\n"
+ " runtime_outputs.\n"
"\n"
" Example for a compiler tool that produces .obj files:\n"
" outputs = [\n"
@@ -555,16 +609,14 @@ const char kTool_Help[] =
"\n"
" link_output [string with substitutions]\n"
" depend_output [string with substitutions]\n"
- " runtime_link_output [string with substitutions]\n"
" Valid for: \"solink\" only (optional)\n"
"\n"
- " These three files specify which of the outputs from the solink\n"
+ " These two files specify which of the outputs from the solink\n"
" tool should be used for linking and dependency tracking. These\n"
" should match entries in the \"outputs\". If unspecified, the\n"
" first item in the \"outputs\" array will be used for all. See\n"
" \"Separate linking and dependencies for shared libraries\"\n"
- " below for more. If link_output is set but runtime_link_output\n"
- " is not set, runtime_link_output defaults to link_output.\n"
+ " below for more.\n"
"\n"
" On Windows, where the tools produce a .dll shared library and\n"
" a .lib import library, you will want the first two to be the\n"
@@ -642,6 +694,14 @@ const char kTool_Help[] =
" rspfile_content = \"{{inputs}} {{solibs}} {{libs}}\"\n"
" }\n"
"\n"
+ " runtime_outputs [string list with substitutions]\n"
+ " Valid for: linker tools\n"
+ "\n"
+ " If specified, this list is the subset of the outputs that should\n"
+ " be added to runtime deps (see \"gn help runtime_deps\"). By\n"
+ " default (if runtime_outputs is empty or unspecified), it will be\n"
+ " the link_output.\n"
+ "\n"
"Expansions for tool variables\n"
"\n"
" All paths are relative to the root build directory, which is the\n"
@@ -915,6 +975,7 @@ Value RunTool(Scope* scope,
}
std::unique_ptr<Tool> tool(new Tool);
+ tool->set_defined_from(function);
if (!ReadPattern(&block_scope, "command", subst_validator, tool.get(),
&Tool::set_command, err) ||
@@ -932,8 +993,8 @@ Value RunTool(Scope* scope,
&Tool::set_link_output, err) ||
!ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(),
&Tool::set_depend_output, err) ||
- !ReadPattern(&block_scope, "runtime_link_output", subst_validator,
- tool.get(), &Tool::set_runtime_link_output, err) ||
+ !ReadPatternList(&block_scope, "runtime_outputs", subst_validator,
+ tool.get(), &Tool::set_runtime_outputs, err) ||
!ReadString(&block_scope, "output_prefix", tool.get(),
&Tool::set_output_prefix, err) ||
!ReadPattern(&block_scope, "default_output_dir", subst_validator,
@@ -944,7 +1005,7 @@ Value RunTool(Scope* scope,
&Tool::set_rspfile, err) ||
!ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(),
&Tool::set_rspfile_content, err) ||
- !ReadLabel(&block_scope, "pool", tool.get(), function, toolchain->label(),
+ !ReadLabel(&block_scope, "pool", tool.get(), toolchain->label(),
&Tool::set_pool, err)) {
return Value();
}
@@ -955,59 +1016,27 @@ Value RunTool(Scope* scope,
tool_type != Toolchain::TYPE_COMPILE_XCASSETS) {
// All tools should have outputs, except the copy, stamp, copy_bundle_data
// and compile_xcassets tools that generate their outputs internally.
- if (!ReadOutputs(&block_scope, function, subst_output_validator,
- tool.get(), err))
+ if (!ReadPatternList(&block_scope, "outputs", subst_output_validator,
+ tool.get(), &Tool::set_outputs, err) ||
+ !ValidateOutputs(tool.get(), err))
return Value();
}
+ if (!ValidateRuntimeOutputs(tool.get(), tool_type, err))
+ return Value();
- // Validate that the link_output, depend_output, and runtime_link_output
- // refer to items in the outputs and aren't defined for irrelevant tool
- // types.
- if (!tool->link_output().empty()) {
- if (tool_type != Toolchain::TYPE_SOLINK &&
- tool_type != Toolchain::TYPE_SOLINK_MODULE) {
- *err = Err(function, "This tool specifies a link_output.",
- "This is only valid for solink and solink_module tools.");
- return Value();
- }
- if (!IsPatternInOutputList(tool->outputs(), tool->link_output())) {
- *err = Err(function, "This tool's link_output is bad.",
- "It must match one of the outputs.");
- return Value();
- }
- }
- if (!tool->depend_output().empty()) {
- if (tool_type != Toolchain::TYPE_SOLINK &&
- tool_type != Toolchain::TYPE_SOLINK_MODULE) {
- *err = Err(function, "This tool specifies a depend_output.",
- "This is only valid for solink and solink_module tools.");
- return Value();
- }
- if (!IsPatternInOutputList(tool->outputs(), tool->depend_output())) {
- *err = Err(function, "This tool's depend_output is bad.",
- "It must match one of the outputs.");
- return Value();
- }
- }
+ // Validate link_output and depend_output.
+ if (!ValidateLinkAndDependOutput(tool.get(), tool_type, tool->link_output(),
+ "link_output", err))
+ return Value();
+ if (!ValidateLinkAndDependOutput(tool.get(), tool_type, tool->depend_output(),
+ "depend_output", err))
+ return Value();
if ((!tool->link_output().empty() && tool->depend_output().empty()) ||
(tool->link_output().empty() && !tool->depend_output().empty())) {
*err = Err(function, "Both link_output and depend_output should either "
"be specified or they should both be empty.");
return Value();
}
- if (!tool->runtime_link_output().empty()) {
- if (tool_type != Toolchain::TYPE_SOLINK &&
- tool_type != Toolchain::TYPE_SOLINK_MODULE) {
- *err = Err(function, "This tool specifies a runtime_link_output.",
- "This is only valid for solink and solink_module tools.");
- return Value();
- }
- if (!IsPatternInOutputList(tool->outputs(), tool->runtime_link_output())) {
- *err = Err(function, "This tool's runtime_link_output is bad.",
- "It must match one of the outputs.");
- return Value();
- }
- }
// Make sure there weren't any vars set in this tool that were unused.
if (!block_scope.CheckForUnusedVars(err))
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/function_toolchain_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698