Index: tools/gn/function_template.cc |
diff --git a/tools/gn/function_template.cc b/tools/gn/function_template.cc |
index 6136f41ec36fab722457bcc6b978b160e1ce7b38..66c6801d2b024def8e982629339a48a77ad72cb0 100644 |
--- a/tools/gn/function_template.cc |
+++ b/tools/gn/function_template.cc |
@@ -15,148 +15,144 @@ const char kTemplate[] = "template"; |
const char kTemplate_HelpShort[] = |
"template: Define a template rule."; |
const char kTemplate_Help[] = |
- "template: Define a template rule.\n" |
- "\n" |
- " A template defines a custom name that acts like a function. It\n" |
- " provides a way to add to the built-in target types.\n" |
- "\n" |
- " The template() function is used to declare a template. To invoke the\n" |
- " template, just use the name of the template like any other target\n" |
- " type.\n" |
- "\n" |
- " Often you will want to declare your template in a special file that\n" |
- " other files will import (see \"gn help import\") so your template\n" |
- " rule can be shared across build files.\n" |
- "\n" |
- "Variables and templates:\n" |
- "\n" |
- " When you call template() it creates a closure around all variables\n" |
- " currently in scope with the code in the template block. When the\n" |
- " template is invoked, the closure will be executed.\n" |
- "\n" |
- " When the template is invoked, the code in the caller is executed and\n" |
- " passed to the template code as an implicit \"invoker\" variable. The\n" |
- " template uses this to read state out of the invoking code.\n" |
- "\n" |
- " One thing explicitly excluded from the closure is the \"current\n" |
- " directory\" against which relative file names are resolved. The\n" |
- " current directory will be that of the invoking code, since typically\n" |
- " that code specifies the file names. This means all files internal\n" |
- " to the template should use absolute names.\n" |
- "\n" |
- " A template will typically forward some or all variables from the\n" |
- " invoking scope to a target that it defines. Often, such variables\n" |
- " might be optional. Use the pattern:\n" |
- "\n" |
- " if (defined(invoker.deps)) {\n" |
- " deps = invoker.deps\n" |
- " }\n" |
- "\n" |
- " The function forward_variables_from() provides a shortcut to forward\n" |
- " one or more or possibly all variables in this manner:\n" |
- "\n" |
- " forward_variables_from(invoker, [\"deps\", \"public_deps\"])\n" |
- "\n" |
- "Target naming:\n" |
- "\n" |
- " Your template should almost always define a built-in target with the\n" |
- " name the template invoker specified. For example, if you have an IDL\n" |
- " template and somebody does:\n" |
- " idl(\"foo\") {...\n" |
- " you will normally want this to expand to something defining a\n" |
- " source_set or static_library named \"foo\" (among other things you may\n" |
- " need). This way, when another target specifies a dependency on\n" |
- " \"foo\", the static_library or source_set will be linked.\n" |
- "\n" |
- " It is also important that any other targets your template expands to\n" |
- " have globally unique names, or you will get collisions.\n" |
- "\n" |
- " Access the invoking name in your template via the implicit\n" |
- " \"target_name\" variable. This should also be the basis for how other\n" |
- " targets that a template expands to ensure uniqueness.\n" |
- "\n" |
- " A typical example would be a template that defines an action to\n" |
- " generate some source files, and a source_set to compile that source.\n" |
- " Your template would name the source_set \"target_name\" because\n" |
- " that's what you want external targets to depend on to link your code.\n" |
- " And you would name the action something like \"${target_name}_action\"\n" |
- " to make it unique. The source set would have a dependency on the\n" |
- " action to make it run.\n" |
- "\n" |
- "Example of defining a template:\n" |
- "\n" |
- " template(\"my_idl\") {\n" |
- " # Be nice and help callers debug problems by checking that the\n" |
- " # variables the template requires are defined. This gives a nice\n" |
- " # message rather than giving the user an error about an\n" |
- " # undefined variable in the file defining the template\n" |
- " #\n" |
- " # You can also use defined() to give default values to variables\n" |
- " # unspecified by the invoker.\n" |
- " assert(defined(invoker.sources),\n" |
- " \"Need sources in $target_name listing the idl files.\")\n" |
- "\n" |
- " # Name of the intermediate target that does the code gen. This must\n" |
- " # incorporate the target name so it's unique across template\n" |
- " # instantiations.\n" |
- " code_gen_target_name = target_name + \"_code_gen\"\n" |
- "\n" |
- " # Intermediate target to convert IDL to C source. Note that the name\n" |
- " # is based on the name the invoker of the template specified. This\n" |
- " # way, each time the template is invoked we get a unique\n" |
- " # intermediate action name (since all target names are in the global\n" |
- " # scope).\n" |
- " action_foreach(code_gen_target_name) {\n" |
- " # Access the scope defined by the invoker via the implicit\n" |
- " # \"invoker\" variable.\n" |
- " sources = invoker.sources\n" |
- "\n" |
- " # Note that we need an absolute path for our script file name.\n" |
- " # The current directory when executing this code will be that of\n" |
- " # the invoker (this is why we can use the \"sources\" directly\n" |
- " # above without having to rebase all of the paths). But if we need\n" |
- " # to reference a script relative to the template file, we'll need\n" |
- " # to use an absolute path instead.\n" |
- " script = \"//tools/idl/idl_code_generator.py\"\n" |
- "\n" |
- " # Tell GN how to expand output names given the sources.\n" |
- " # See \"gn help source_expansion\" for more.\n" |
- " outputs = [ \"$target_gen_dir/{{source_name_part}}.cc\",\n" |
- " \"$target_gen_dir/{{source_name_part}}.h\" ]\n" |
- " }\n" |
- "\n" |
- " # Name the source set the same as the template invocation so\n" |
- " # instancing this template produces something that other targets\n" |
- " # can link to in their deps.\n" |
- " source_set(target_name) {\n" |
- " # Generates the list of sources, we get these from the\n" |
- " # action_foreach above.\n" |
- " sources = get_target_outputs(\":$code_gen_target_name\")\n" |
- "\n" |
- " # This target depends on the files produced by the above code gen\n" |
- " # target.\n" |
- " deps = [ \":$code_gen_target_name\" ]\n" |
- " }\n" |
- " }\n" |
- "\n" |
- "Example of invoking the resulting template:\n" |
- "\n" |
- " # This calls the template code above, defining target_name to be\n" |
- " # \"foo_idl_files\" and \"invoker\" to be the set of stuff defined in\n" |
- " # the curly brackets.\n" |
- " my_idl(\"foo_idl_files\") {\n" |
- " # Goes into the template as \"invoker.sources\".\n" |
- " sources = [ \"foo.idl\", \"bar.idl\" ]\n" |
- " }\n" |
- "\n" |
- " # Here is a target that depends on our template.\n" |
- " executable(\"my_exe\") {\n" |
- " # Depend on the name we gave the template call above. Internally,\n" |
- " # this will produce a dependency from executable to the source_set\n" |
- " # inside the template (since it has this name), which will in turn\n" |
- " # depend on the code gen action.\n" |
- " deps = [ \":foo_idl_files\" ]\n" |
- " }\n"; |
+ R"(template: Define a template rule. |
+ |
+ A template defines a custom name that acts like a function. It provides a way |
+ to add to the built-in target types. |
+ |
+ The template() function is used to declare a template. To invoke the |
+ template, just use the name of the template like any other target type. |
+ |
+ Often you will want to declare your template in a special file that other |
+ files will import (see "gn help import") so your template rule can be shared |
+ across build files. |
+ |
+Variables and templates: |
+ |
+ When you call template() it creates a closure around all variables currently |
+ in scope with the code in the template block. When the template is invoked, |
+ the closure will be executed. |
+ |
+ When the template is invoked, the code in the caller is executed and passed |
+ to the template code as an implicit "invoker" variable. The template uses |
+ this to read state out of the invoking code. |
+ |
+ One thing explicitly excluded from the closure is the "current directory" |
+ against which relative file names are resolved. The current directory will be |
+ that of the invoking code, since typically that code specifies the file |
+ names. This means all files internal to the template should use absolute |
+ names. |
+ |
+ A template will typically forward some or all variables from the invoking |
+ scope to a target that it defines. Often, such variables might be optional. |
+ Use the pattern: |
+ |
+ if (defined(invoker.deps)) { |
+ deps = invoker.deps |
+ } |
+ |
+ The function forward_variables_from() provides a shortcut to forward one or |
+ more or possibly all variables in this manner: |
+ |
+ forward_variables_from(invoker, ["deps", "public_deps"]) |
+ |
+Target naming |
+ |
+ Your template should almost always define a built-in target with the name the |
+ template invoker specified. For example, if you have an IDL template and |
+ somebody does: |
+ idl("foo") {... |
+ you will normally want this to expand to something defining a source_set or |
+ static_library named "foo" (among other things you may need). This way, when |
+ another target specifies a dependency on "foo", the static_library or |
+ source_set will be linked. |
+ |
+ It is also important that any other targets your template expands to have |
+ unique names, or you will get collisions. |
+ |
+ Access the invoking name in your template via the implicit "target_name" |
+ variable. This should also be the basis for how other targets that a template |
+ expands to ensure uniqueness. |
+ |
+ A typical example would be a template that defines an action to generate some |
+ source files, and a source_set to compile that source. Your template would |
+ name the source_set "target_name" because that's what you want external |
+ targets to depend on to link your code. And you would name the action |
+ something like "${target_name}_action" to make it unique. The source set |
+ would have a dependency on the action to make it run. |
+ |
+Example of defining a template |
+ |
+ template("my_idl") { |
+ # Be nice and help callers debug problems by checking that the variables |
+ # the template requires are defined. This gives a nice message rather than |
+ # giving the user an error about an undefined variable in the file defining |
+ # the template |
+ # |
+ # You can also use defined() to give default values to variables |
+ # unspecified by the invoker. |
+ assert(defined(invoker.sources), |
+ "Need sources in $target_name listing the idl files.") |
+ |
+ # Name of the intermediate target that does the code gen. This must |
+ # incorporate the target name so it's unique across template |
+ # instantiations. |
+ code_gen_target_name = target_name + "_code_gen" |
+ |
+ # Intermediate target to convert IDL to C source. Note that the name is |
+ # based on the name the invoker of the template specified. This way, each |
+ # time the template is invoked we get a unique intermediate action name |
+ # (since all target names are in the global scope). |
+ action_foreach(code_gen_target_name) { |
+ # Access the scope defined by the invoker via the implicit "invoker" |
+ # variable. |
+ sources = invoker.sources |
+ |
+ # Note that we need an absolute path for our script file name. The |
+ # current directory when executing this code will be that of the invoker |
+ # (this is why we can use the "sources" directly above without having to |
+ # rebase all of the paths). But if we need to reference a script relative |
+ # to the template file, we'll need to use an absolute path instead. |
+ script = "//tools/idl/idl_code_generator.py" |
+ |
+ # Tell GN how to expand output names given the sources. |
+ # See "gn help source_expansion" for more. |
+ outputs = [ "$target_gen_dir/{{source_name_part}}.cc", |
+ "$target_gen_dir/{{source_name_part}}.h" ] |
+ } |
+ |
+ # Name the source set the same as the template invocation so instancing |
+ # this template produces something that other targets can link to in their |
+ # deps. |
+ source_set(target_name) { |
+ # Generates the list of sources, we get these from the action_foreach |
+ # above. |
+ sources = get_target_outputs(":$code_gen_target_name") |
+ |
+ # This target depends on the files produced by the above code gen target. |
+ deps = [ ":$code_gen_target_name" ] |
+ } |
+ } |
+ |
+Example of invoking the resulting template |
+ |
+ # This calls the template code above, defining target_name to be |
+ # "foo_idl_files" and "invoker" to be the set of stuff defined in the curly |
+ # brackets. |
+ my_idl("foo_idl_files") { |
+ # Goes into the template as "invoker.sources". |
+ sources = [ "foo.idl", "bar.idl" ] |
+ } |
+ |
+ # Here is a target that depends on our template. |
+ executable("my_exe") { |
+ # Depend on the name we gave the template call above. Internally, this will |
+ # produce a dependency from executable to the source_set inside the |
+ # template (since it has this name), which will in turn depend on the code |
+ # gen action. |
+ deps = [ ":foo_idl_files" ] |
+ } |
+)"; |
Value RunTemplate(Scope* scope, |
const FunctionCallNode* function, |