• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "gn/functions.h"
6 
7 #include "gn/config_values_generator.h"
8 #include "gn/err.h"
9 #include "gn/parse_tree.h"
10 #include "gn/scope.h"
11 #include "gn/target_generator.h"
12 #include "gn/template.h"
13 #include "gn/value.h"
14 #include "gn/variables.h"
15 
16 #define DEPENDENT_CONFIG_VARS \
17   "  Dependent configs: all_dependent_configs, public_configs\n"
18 #define DEPS_VARS                                                         \
19   "  Deps: assert_no_deps, data_deps, deps, public_deps, runtime_deps,\n" \
20   "        write_runtime_deps\n"
21 #define GENERAL_TARGET_VARS                                                \
22   "  General: check_includes, configs, data, friend, inputs, metadata,\n"  \
23   "           output_extension, output_name, public, sources, testonly,\n" \
24   "           visibility\n"
25 #define RUST_VARS "  Rust variables: aliased_deps, crate_root, crate_name\n"
26 #define RUST_SHARED_VARS \
27   "  Rust variables: aliased_deps, crate_root, crate_name, crate_type\n"
28 #define ACTION_VARS                                                            \
29   "  Action variables: args, bridge_header, configs, data, depfile,\n"         \
30   "                    framework_dirs, inputs, mnemonic, module_deps,\n"       \
31   "                    module_name, outputs*, pool, response_file_contents,\n" \
32   "                    script*, sources\n"
33 
34 namespace functions {
35 
36 namespace {
37 
ExecuteGenericTarget(const char * target_type,Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)38 Value ExecuteGenericTarget(const char* target_type,
39                            Scope* scope,
40                            const FunctionCallNode* function,
41                            const std::vector<Value>& args,
42                            BlockNode* block,
43                            Err* err) {
44   NonNestableBlock non_nestable(scope, function, "target");
45   if (!non_nestable.Enter(err))
46     return Value();
47 
48   if (!EnsureNotProcessingImport(function, scope, err) ||
49       !EnsureNotProcessingBuildConfig(function, scope, err))
50     return Value();
51   Scope block_scope(scope);
52   if (!FillTargetBlockScope(scope, function, target_type, block, args,
53                             &block_scope, err))
54     return Value();
55 
56   block->Execute(&block_scope, err);
57   if (err->has_error())
58     return Value();
59 
60   TargetGenerator::GenerateTarget(&block_scope, function, args, target_type,
61                                   err);
62   if (err->has_error())
63     return Value();
64 
65   block_scope.CheckForUnusedVars(err);
66   return Value();
67 }
68 
69 }  // namespace
70 
71 // action ----------------------------------------------------------------------
72 
73 // Common help paragraph on script runtime execution directories.
74 #define SCRIPT_EXECUTION_CONTEXT                                              \
75   "\n"                                                                        \
76   "  The script will be executed with the given arguments with the current\n" \
77   "  directory being that of the root build directory. If you pass files\n"   \
78   "  to your script, see \"gn help rebase_path\" for how to convert\n"        \
79   "  file names to be relative to the build directory (file names in the\n"   \
80   "  sources, outputs, and inputs will be all treated as relative to the\n"   \
81   "  current build file and converted as needed automatically).\n"            \
82   "\n"                                                                        \
83   "  GN sets Ninja's flag 'restat = 1` for all action commands. This means\n" \
84   "  that Ninja will check the timestamp of the output after the action\n"    \
85   "  completes. If output timestamp is unchanged, the step will be treated\n" \
86   "  as if it never needed to be rebuilt, potentially eliminating some\n"     \
87   "  downstream steps for incremental builds. Scripts can improve build\n"    \
88   "  performance by taking care not to change the timstamp of the output\n"   \
89   "  file(s) if the contents have not changed.\n"
90 
91 // Common help paragraph on script output directories.
92 #define SCRIPT_EXECUTION_OUTPUTS                                           \
93   "\n"                                                                     \
94   "  All output files must be inside the output directory of the build.\n" \
95   "  You would generally use |$target_out_dir| or |$target_gen_dir| to\n"  \
96   "  reference the output or generated intermediate file directories,\n"   \
97   "  respectively.\n"
98 
99 #define ACTION_DEPS                                                           \
100   "\n"                                                                        \
101   "  The \"deps\" and \"public_deps\" for an action will always be\n"         \
102   "  completed before any part of the action is run so it can depend on\n"    \
103   "  the output of previous steps. The \"data_deps\" will be built if the\n"  \
104   "  action is built, but may not have completed before all steps of the\n"   \
105   "  action are started. This can give additional parallelism in the build\n" \
106   "  for runtime-only dependencies.\n"
107 
108 // Common help paragraph on targets that can use different languages.
109 #define LANGUAGE_HELP                                                     \
110   "\n"                                                                    \
111   "  The tools and commands used to create this target type will be\n"    \
112   "  determined by the source files in its sources. Targets containing\n" \
113   "  multiple compiler-incompatible languages are not allowed (e.g. a\n"  \
114   "  target containing both C and C++ sources is acceptable, but a\n"     \
115   "  target containing C and Rust sources is not).\n"
116 
117 const char kAction[] = "action";
118 const char kAction_HelpShort[] =
119     "action: Declare a target that runs a script a single time.";
120 const char kAction_Help[] =
121     R"(action: Declare a target that runs a script a single time.
122 
123   This target type allows you to run a script a single time to produce one or
124   more output files. If you want to run a script once for each of a set of
125   input files, see "gn help action_foreach".
126 
127 Inputs
128 
129   In an action the "sources" and "inputs" are treated the same: they're both
130   input dependencies on script execution with no special handling. If you want
131   to pass the sources to your script, you must do so explicitly by including
132   them in the "args". Note also that this means there is no special handling of
133   paths since GN doesn't know which of the args are paths and not. You will
134   want to use rebase_path() to convert paths to be relative to the
135   root_build_dir.
136 
137   You can dynamically write input dependencies (for incremental rebuilds if an
138   input file changes) by writing a depfile when the script is run (see "gn help
139   depfile"). This is more flexible than "inputs".
140 
141   If the command line length is very long, you can use response files to pass
142   args to your script. See "gn help response_file_contents".
143 
144   It is recommended you put inputs to your script in the "sources" variable,
145   and stuff like other Python files required to run your script in the "inputs"
146   variable.
147 
148   Actions can take the configs and public_configs lists, as well as any of the
149   configs variables (defines, include_dirs, etc.) set directly on the target.
150   These behave exactly as they would on a binary target and can be accessed
151   using substitution patterns in the script args (see "gn help args") to
152   implement custom compiler-like tools.
153 )"
154 
155     ACTION_DEPS
156 
157     R"(
158 Outputs
159 
160   You should specify files created by your script by specifying them in the
161   "outputs".
162 )"
163 
164     SCRIPT_EXECUTION_CONTEXT
165 
166     R"(
167 File name handling
168 )"
169 
170     SCRIPT_EXECUTION_OUTPUTS
171 
172     R"(
173 Variables
174 
175 )" CONFIG_VALUES_VARS_HELP DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS ACTION_VARS
176 
177     R"(  * = required
178 
179 Example
180 
181   action("run_this_guy_once") {
182     script = "doprocessing.py"
183     sources = [ "my_configuration.txt" ]
184     outputs = [ "$target_gen_dir/insightful_output.txt" ]
185 
186     # Our script imports this Python file so we want to rebuild if it changes.
187     inputs = [ "helper_library.py" ]
188 
189     # Note that we have to manually pass the sources to our script if the
190     # script needs them as inputs.
191     args = [ "--out", rebase_path(target_gen_dir, root_build_dir) ] +
192            rebase_path(sources, root_build_dir)
193   }
194 )";
195 
RunAction(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)196 Value RunAction(Scope* scope,
197                 const FunctionCallNode* function,
198                 const std::vector<Value>& args,
199                 BlockNode* block,
200                 Err* err) {
201   return ExecuteGenericTarget(functions::kAction, scope, function, args, block,
202                               err);
203 }
204 
205 // action_foreach --------------------------------------------------------------
206 
207 const char kActionForEach[] = "action_foreach";
208 const char kActionForEach_HelpShort[] =
209     "action_foreach: Declare a target that runs a script over a set of files.";
210 const char kActionForEach_Help[] =
211     R"(action_foreach: Declare a target that runs a script over a set of files.
212 
213   This target type allows you to run a script once-per-file over a set of
214   sources. If you want to run a script once that takes many files as input, see
215   "gn help action".
216 
217 Inputs
218 
219   The script will be run once per file in the "sources" variable. The "outputs"
220   variable should specify one or more files with a source expansion pattern in
221   it (see "gn help source_expansion"). The output file(s) for each script
222   invocation should be unique. Normally you use "{{source_name_part}}" in each
223   output file.
224 
225   If your script takes additional data as input, such as a shared configuration
226   file or a Python module it uses, those files should be listed in the "inputs"
227   variable. These files are treated as dependencies of each script invocation.
228 
229   If the command line length is very long, you can use response files to pass
230   args to your script. See "gn help response_file_contents".
231 
232   You can dynamically write input dependencies (for incremental rebuilds if an
233   input file changes) by writing a depfile when the script is run (see "gn help
234   depfile"). This is more flexible than "inputs".
235 )" ACTION_DEPS
236     R"(
237 Outputs
238 )" SCRIPT_EXECUTION_CONTEXT
239     R"(
240 File name handling
241 )" SCRIPT_EXECUTION_OUTPUTS
242     R"(
243 Variables
244 
245 )" CONFIG_VALUES_VARS_HELP DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS ACTION_VARS
246 
247     R"(  * = required
248 
249 Example
250 
251   # Runs the script over each IDL file. The IDL script will generate both a .cc
252   # and a .h file for each input.
253   action_foreach("my_idl") {
254     script = "idl_processor.py"
255     sources = [ "foo.idl", "bar.idl" ]
256 
257     # Causes ninja to output "IDL <label>" rather than the default
258     # "ACTION <label>" when building this action.
259     mnemonic = "IDL"
260 
261     # Our script reads this file each time, so we need to list it as a
262     # dependency so we can rebuild if it changes.
263     inputs = [ "my_configuration.txt" ]
264 
265     # Transformation from source file name to output file names.
266     outputs = [ "$target_gen_dir/{{source_name_part}}.h",
267                 "$target_gen_dir/{{source_name_part}}.cc" ]
268 
269     # Note that since "args" is opaque to GN, if you specify paths here, you
270     # will need to convert it to be relative to the build directory using
271     # rebase_path().
272     args = [
273       "{{source}}",
274       "-o",
275       rebase_path(target_gen_dir, root_build_dir) +
276         "/{{source_name_part}}.h" ]
277   }
278 )";
279 
RunActionForEach(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)280 Value RunActionForEach(Scope* scope,
281                        const FunctionCallNode* function,
282                        const std::vector<Value>& args,
283                        BlockNode* block,
284                        Err* err) {
285   return ExecuteGenericTarget(functions::kActionForEach, scope, function, args,
286                               block, err);
287 }
288 
289 // bundle_data -----------------------------------------------------------------
290 
291 const char kBundleData[] = "bundle_data";
292 const char kBundleData_HelpShort[] =
293     "bundle_data: [iOS/macOS] Declare a target without output.";
294 const char kBundleData_Help[] =
295     R"(bundle_data: [iOS/macOS] Declare a target without output.
296 
297   This target type allows one to declare data that is required at runtime. It is
298   used to inform "create_bundle" targets of the files to copy into generated
299   bundle, see "gn help create_bundle" for help.
300 
301   The target must define a list of files as "sources" and a single "outputs".
302   If there are multiple files, source expansions must be used to express the
303   output. The output must reference a file inside of {{bundle_root_dir}}.
304 
305   This target can be used on all platforms though it is designed only to
306   generate iOS/macOS bundle. In cross-platform projects, it is advised to put it
307   behind iOS/macOS conditionals.
308 
309   If any source files in a bundle_data target match `*/*.xcassets/*` then they
310   will be considered part of an assets catalog, and instead of being copied to
311   the final bundle the assets catalog itself will be added to the inputs of the
312   assets catalog compilation step. See "compile_xcassets" tool.
313 
314   See "gn help create_bundle" for more information.
315 
316 Variables
317 
318 )" DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS
319 
320     R"(  Bundle-specific: sources*, outputs*
321   * = required
322 
323 Examples
324 
325   bundle_data("icudata") {
326     sources = [ "sources/data/in/icudtl.dat" ]
327     outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
328   }
329 
330   bundle_data("base_unittests_bundle_data]") {
331     sources = [ "test/data" ]
332     outputs = [
333       "{{bundle_resources_dir}}/{{source_root_relative_dir}}/" +
334           "{{source_file_part}}"
335     ]
336   }
337 
338   bundle_data("material_typography_bundle_data") {
339     sources = [
340       "src/MaterialTypography.bundle/Roboto-Bold.ttf",
341       "src/MaterialTypography.bundle/Roboto-Italic.ttf",
342       "src/MaterialTypography.bundle/Roboto-Regular.ttf",
343       "src/MaterialTypography.bundle/Roboto-Thin.ttf",
344     ]
345     outputs = [
346       "{{bundle_resources_dir}}/MaterialTypography.bundle/"
347           "{{source_file_part}}"
348     ]
349   }
350 )";
351 
RunBundleData(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)352 Value RunBundleData(Scope* scope,
353                     const FunctionCallNode* function,
354                     const std::vector<Value>& args,
355                     BlockNode* block,
356                     Err* err) {
357   return ExecuteGenericTarget(functions::kBundleData, scope, function, args,
358                               block, err);
359 }
360 
361 // create_bundle ---------------------------------------------------------------
362 
363 const char kCreateBundle[] = "create_bundle";
364 const char kCreateBundle_HelpShort[] =
365     "create_bundle: [iOS/macOS] Build an iOS or macOS bundle.";
366 const char kCreateBundle_Help[] =
367     R"(create_bundle: [ios/macOS] Build an iOS or macOS bundle.
368 
369   This target generates an iOS or macOS bundle (which is a directory with a
370   well-know structure). This target does not define any sources, instead they
371   are computed from all "bundle_data" target this one depends on transitively
372   (the recursion stops at "create_bundle" targets).
373 
374   The "bundle_*_dir" are be used for the expansion of {{bundle_*_dir}} rules in
375   "bundle_data" outputs. The properties are optional but must be defined if any
376   of the "bundle_data" target use them.
377 
378   This target can be used on all platforms though it is designed only to
379   generate iOS or macOS bundle. In cross-platform projects, it is advised to put
380   it behind iOS/macOS conditionals.
381 
382   If a create_bundle is specified as a data_deps for another target, the bundle
383   is considered a leaf, and its public and private dependencies will not
384   contribute to any data or data_deps. Required runtime dependencies should be
385   placed in the bundle. A create_bundle can declare its own explicit data and
386   data_deps, however.
387 
388 Post-processing
389 
390   Some bundle needs to be post-processed as part of the build (e.g. on iOS all
391   application needs to be code signed to run on a device). The post processing
392   step can be configured via the post_processing_script variable.
393 
394   If set, `post_processing_script` is the path of a script that invoked after
395   all files have been moved into the bundle. The script must not change any file
396   in the bundle, but may add new files.
397 
398   If `post_processing_script` is defined, then `post_processing_outputs` must
399   be defined and non-empty to inform when the script needs to be re-run. The
400   `post_processing_args` will be passed as is to the script (so path have to be
401   rebased) and additional inputs may be listed via `post_processing_sources`.
402 
403 Migration
404 
405   The post-processing step used to be limited to code-signing. The properties
406   used to be named `code_signing_$name` instead of `post_processing_$name`. The
407   old names are still accepted as alias to facilitate migration but a warning
408   will be emitted and the alias eventually be removed.
409 
410 Variables
411 
412 )" DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS
413 
414     R"(  Bundle vars: bundle_root_dir, bundle_contents_dir, bundle_resources_dir,
415                bundle_executable_dir, bundle_deps_filter, product_type,
416                post_processing_args, post_processing_script,
417                post_processing_sources, post_processing_outputs,
418                xcode_extra_attributes, xcode_test_application_name,
419                partial_info_plist
420 
421 Example
422 
423   # Defines a template to create an application. On most platform, this is just
424   # an alias for an "executable" target, but on iOS/macOS, it builds an
425   # application bundle.
426   template("app") {
427     if (!is_ios && !is_mac) {
428       executable(target_name) {
429         forward_variables_from(invoker, "*")
430       }
431     } else {
432       app_name = target_name
433       gen_path = target_gen_dir
434 
435       action("${app_name}_generate_info_plist") {
436         script = [ "//build/ios/ios_gen_plist.py" ]
437         sources = [ "templates/Info.plist" ]
438         outputs = [ "$gen_path/Info.plist" ]
439         args = rebase_path(sources, root_build_dir) +
440                rebase_path(outputs, root_build_dir)
441       }
442 
443       bundle_data("${app_name}_bundle_info_plist") {
444         public_deps = [ ":${app_name}_generate_info_plist" ]
445         sources = [ "$gen_path/Info.plist" ]
446         outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
447       }
448 
449       executable("${app_name}_generate_executable") {
450         forward_variables_from(invoker, "*", [
451                                                "output_name",
452                                                "visibility",
453                                              ])
454         output_name =
455             rebase_path("$gen_path/$app_name", root_build_dir)
456       }
457 
458       code_signing =
459           defined(invoker.code_signing) && invoker.code_signing
460 
461       if (!is_ios || !code_signing) {
462         bundle_data("${app_name}_bundle_executable") {
463           public_deps = [ ":${app_name}_generate_executable" ]
464           sources = [ "$gen_path/$app_name" ]
465           outputs = [ "{{bundle_executable_dir}}/$app_name" ]
466         }
467       }
468 
469       create_bundle("$app_name.app") {
470         product_type = "com.apple.product-type.application"
471 
472         if (is_ios) {
473           bundle_root_dir = "$root_build_dir/$target_name"
474           bundle_contents_dir = bundle_root_dir
475           bundle_resources_dir = bundle_contents_dir
476           bundle_executable_dir = bundle_contents_dir
477 
478           xcode_extra_attributes = {
479             ONLY_ACTIVE_ARCH = "YES"
480             DEBUG_INFORMATION_FORMAT = "dwarf"
481           }
482         } else {
483           bundle_root_dir = "$root_build_dir/$target_name"
484           bundle_contents_dir  = "$bundle_root_dir/Contents"
485           bundle_resources_dir = "$bundle_contents_dir/Resources"
486           bundle_executable_dir = "$bundle_contents_dir/MacOS"
487         }
488         deps = [ ":${app_name}_bundle_info_plist" ]
489         if (is_ios && code_signing) {
490           deps += [ ":${app_name}_generate_executable" ]
491           post_processing_script = "//build/config/ios/codesign.py"
492           post_processing_sources = [
493             invoker.entitlements_path,
494             "$target_gen_dir/$app_name",
495           ]
496           post_processing_outputs = [
497             "$bundle_root_dir/$app_name",
498             "$bundle_root_dir/_CodeSignature/CodeResources",
499             "$bundle_root_dir/embedded.mobileprovision",
500             "$target_gen_dir/$app_name.xcent",
501           ]
502           post_processing_args = [
503             "-i=" + ios_post_processing_identity,
504             "-b=" + rebase_path(
505                 "$target_gen_dir/$app_name", root_build_dir),
506             "-e=" + rebase_path(
507                 invoker.entitlements_path, root_build_dir),
508             "-e=" + rebase_path(
509                 "$target_gen_dir/$app_name.xcent", root_build_dir),
510             rebase_path(bundle_root_dir, root_build_dir),
511           ]
512         } else {
513           deps += [ ":${app_name}_bundle_executable" ]
514         }
515       }
516     }
517   }
518 )";
519 
RunCreateBundle(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)520 Value RunCreateBundle(Scope* scope,
521                       const FunctionCallNode* function,
522                       const std::vector<Value>& args,
523                       BlockNode* block,
524                       Err* err) {
525   return ExecuteGenericTarget(functions::kCreateBundle, scope, function, args,
526                               block, err);
527 }
528 
529 // copy ------------------------------------------------------------------------
530 
531 const char kCopy[] = "copy";
532 const char kCopy_HelpShort[] = "copy: Declare a target that copies files.";
533 const char kCopy_Help[] =
534     R"(copy: Declare a target that copies files.
535 
536 File name handling
537 
538   All output files must be inside the output directory of the build. You would
539   generally use |$target_out_dir| or |$target_gen_dir| to reference the output
540   or generated intermediate file directories, respectively.
541 
542   Both "sources" and "outputs" must be specified. Sources can include as many
543   files as you want, but there can only be one item in the outputs list (plural
544   is used for the name for consistency with other target types).
545 
546   If there is more than one source file, your output name should specify a
547   mapping from each source file to an output file name using source expansion
548   (see "gn help source_expansion"). The placeholders will look like
549   "{{source_name_part}}", for example.
550 
551   If you want to copy the output of a previous build step, the target that
552   generates the file to copy must be reachable from the deps or public_deps of
553   the copy target.
554 
555 Variables
556 
557 )" DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS
558 
559     R"(  Copy variables: sources*, outputs*
560   * = required
561 
562 Examples
563 
564   # Write a rule that copies a checked-in DLL to the output directory.
565   copy("mydll") {
566     sources = [ "mydll.dll" ]
567     outputs = [ "$target_out_dir/mydll.dll" ]
568   }
569 
570   # Write a rule to copy several files to the target generated files directory.
571   copy("myfiles") {
572     sources = [ "data1.dat", "data2.dat", "data3.dat" ]
573 
574     # Use source expansion to generate output files with the corresponding file
575     # names in the gen dir. This will just copy each file.
576     outputs = [ "$target_gen_dir/{{source_file_part}}" ]
577   }
578 
579   # Copy the output of a generated executable.
580   copy("package_melon") {
581     # This example uses get_label_info() to compute the output directory of the
582     # dependency. This allows the copy rule to work regardless of the toolchain.
583     #
584     # In some cases (particularly actions defined previously in the same file)
585     # you can use get_target_outputs() to get the input file which can eliminate
586     # the assumptions about the output file name of the dependency.
587 
588     input_dir = get_label_info("//src/tools/melon", "root_out_dir");
589     sources = [ "$input_dir/melon" ]
590 
591     outputs = [ "$target_gen_dir/{{source_file_part}}" ]
592 
593     # Depend on the target to build the file before copying.
594     deps = [ "//src/tools/melon" ]
595   }
596 
597 Variables
598 
599   copy_linkable_file
600 )";
601 
RunCopy(const FunctionCallNode * function,const std::vector<Value> & args,Scope * scope,Err * err)602 Value RunCopy(const FunctionCallNode* function,
603               const std::vector<Value>& args,
604               Scope* scope,
605               Err* err) {
606   if (!EnsureNotProcessingImport(function, scope, err) ||
607       !EnsureNotProcessingBuildConfig(function, scope, err))
608     return Value();
609   TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err);
610   return Value();
611 }
612 
613 // executable ------------------------------------------------------------------
614 
615 const char kExecutable[] = "executable";
616 const char kExecutable_HelpShort[] =
617     "executable: Declare an executable target.";
618 const char kExecutable_Help[] =
619     R"(executable: Declare an executable target.
620 
621 Language and compilation
622 )" LANGUAGE_HELP
623     R"(
624 
625 Variables
626 
627 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
628         RUST_VARS;
629 
630 Value RunExecutable(Scope* scope,
631                     const FunctionCallNode* function,
632                     const std::vector<Value>& args,
633                     BlockNode* block,
634                     Err* err) {
635   return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
636                               block, err);
637 }
638 
639 // group -----------------------------------------------------------------------
640 
641 const char kGroup[] = "group";
642 const char kGroup_HelpShort[] = "group: Declare a named group of targets.";
643 const char kGroup_Help[] =
644     R"(group: Declare a named group of targets.
645 
646   This target type allows you to create meta-targets that just collect a set of
647   dependencies into one named target. Groups can additionally specify configs
648   that apply to their dependents.
649 
650 Variables
651 
652 )" DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
653 
654     R"(
655 Example
656 
657   group("all") {
658     deps = [
659       "//project:runner",
660       "//project:unit_tests",
661     ]
662   }
663 )";
664 
RunGroup(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)665 Value RunGroup(Scope* scope,
666                const FunctionCallNode* function,
667                const std::vector<Value>& args,
668                BlockNode* block,
669                Err* err) {
670   return ExecuteGenericTarget(functions::kGroup, scope, function, args, block,
671                               err);
672 }
673 
674 // loadable_module -------------------------------------------------------------
675 
676 const char kLoadableModule[] = "loadable_module";
677 const char kLoadableModule_HelpShort[] =
678     "loadable_module: Declare a loadable module target.";
679 const char kLoadableModule_Help[] =
680     R"(loadable_module: Declare a loadable module target.
681 
682   This target type allows you to create an object file that is (and can only
683   be) loaded and unloaded at runtime.
684 
685   A loadable module will be specified on the linker line for targets listing
686   the loadable module in its "deps". If you don't want this (if you don't need
687   to dynamically load the library at runtime), then you should use a
688   "shared_library" target type instead.
689 
690 Language and compilation
691 )" LANGUAGE_HELP
692     R"(
693 
694 Variables
695 
696 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
697         RUST_SHARED_VARS;
698 
699 Value RunLoadableModule(Scope* scope,
700                         const FunctionCallNode* function,
701                         const std::vector<Value>& args,
702                         BlockNode* block,
703                         Err* err) {
704   return ExecuteGenericTarget(functions::kLoadableModule, scope, function, args,
705                               block, err);
706 }
707 
708 // rust_library ----------------------------------------------------------------
709 
710 const char kRustLibrary[] = "rust_library";
711 const char kRustLibrary_HelpShort[] =
712     "rust_library: Declare a Rust library target.";
713 const char kRustLibrary_Help[] =
714     R"(rust_library: Declare a Rust library target.
715 
716   A Rust library is an archive containing additional rust-c provided metadata.
717   These are the files produced by the rustc compiler with the `.rlib`
718   extension, and are the intermediate step for most Rust-based binaries.
719 
720 Language and compilation
721 )" LANGUAGE_HELP
722     R"(
723 
724 Variables
725 
726 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
727         RUST_VARS;
728 Value RunRustLibrary(Scope* scope,
729                      const FunctionCallNode* function,
730                      const std::vector<Value>& args,
731                      BlockNode* block,
732                      Err* err) {
733   return ExecuteGenericTarget(functions::kRustLibrary, scope, function, args,
734                               block, err);
735 }
736 
737 // rust_proc_macro
738 // ----------------------------------------------------------------
739 
740 const char kRustProcMacro[] = "rust_proc_macro";
741 const char kRustProcMacro_HelpShort[] =
742     "rust_proc_macro: Declare a Rust procedural macro target.";
743 const char kRustProcMacro_Help[] =
744     R"(rust_proc_macro: Declare a Rust procedural macro target.
745 
746   A Rust procedural macro allows creating syntax extensions as execution of a
747   function. They are compiled as dynamic libraries and used by the compiler at
748   runtime.
749 
750   Their use is the same as of other Rust libraries, but their build has some
751   additional restrictions in terms of supported flags.
752 
753 Language and compilation
754 )" LANGUAGE_HELP
755     R"(
756 
757 Variables
758 
759 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
760         RUST_VARS;
761 Value RunRustProcMacro(Scope* scope,
762                        const FunctionCallNode* function,
763                        const std::vector<Value>& args,
764                        BlockNode* block,
765                        Err* err) {
766   return ExecuteGenericTarget(functions::kRustProcMacro, scope, function, args,
767                               block, err);
768 }
769 
770 // shared_library --------------------------------------------------------------
771 
772 const char kSharedLibrary[] = "shared_library";
773 const char kSharedLibrary_HelpShort[] =
774     "shared_library: Declare a shared library target.";
775 const char kSharedLibrary_Help[] =
776     R"(shared_library: Declare a shared library target.
777 
778   A shared library will be specified on the linker line for targets listing the
779   shared library in its "deps". If you don't want this (say you dynamically
780   load the library at runtime), then you should depend on the shared library
781   via "data_deps" or, on Darwin platforms, use a "loadable_module" target type
782   instead.
783 
784 Language and compilation
785 )" LANGUAGE_HELP
786     R"(
787 
788 Variables
789 
790 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
791         RUST_SHARED_VARS;
792 
793 Value RunSharedLibrary(Scope* scope,
794                        const FunctionCallNode* function,
795                        const std::vector<Value>& args,
796                        BlockNode* block,
797                        Err* err) {
798   return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args,
799                               block, err);
800 }
801 
802 // source_set ------------------------------------------------------------------
803 
804 const char kSourceSet[] = "source_set";
805 const char kSourceSet_HelpShort[] = "source_set: Declare a source set target.";
806 const char kSourceSet_Help[] =
807     R"(source_set: Declare a source set target.
808 
809   Only C-language source sets are supported at the moment.
810 
811 C-language source_sets
812 
813   A source set is a collection of sources that get compiled, but are not linked
814   to produce any kind of library. Instead, the resulting object files are
815   implicitly added to the linker line of all targets that depend on the source
816   set.
817 
818   In most cases, a source set will behave like a static library, except no
819   actual library file will be produced. This will make the build go a little
820   faster by skipping creation of a large static library, while maintaining the
821   organizational benefits of focused build targets.
822 
823   The main difference between a source set and a static library is around
824   handling of exported symbols. Most linkers assume declaring a function
825   exported means exported from the static library. The linker can then do dead
826   code elimination to delete code not reachable from exported functions.
827 
828   A source set will not do this code elimination since there is no link step.
829   This allows you to link many source sets into a shared library and have the
830   "exported symbol" notation indicate "export from the final shared library and
831   not from the intermediate targets." There is no way to express this concept
832   when linking multiple static libraries into a shared library.
833 
834 Variables
835 
836 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS;
837 
838 Value RunSourceSet(Scope* scope,
839                    const FunctionCallNode* function,
840                    const std::vector<Value>& args,
841                    BlockNode* block,
842                    Err* err) {
843   return ExecuteGenericTarget(functions::kSourceSet, scope, function, args,
844                               block, err);
845 }
846 
847 // static_library --------------------------------------------------------------
848 
849 const char kStaticLibrary[] = "static_library";
850 const char kStaticLibrary_HelpShort[] =
851     "static_library: Declare a static library target.";
852 const char kStaticLibrary_Help[] =
853     R"(static_library: Declare a static library target.
854 
855   Make a ".a" / ".lib" file.
856 
857   If you only need the static library for intermediate results in the build,
858   you should consider a source_set instead since it will skip the (potentially
859   slow) step of creating the intermediate library file.
860 
861 Variables
862 
863   complete_static_lib
864 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS RUST_VARS
865         LANGUAGE_HELP;
866 
867 Value RunStaticLibrary(Scope* scope,
868                        const FunctionCallNode* function,
869                        const std::vector<Value>& args,
870                        BlockNode* block,
871                        Err* err) {
872   return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args,
873                               block, err);
874 }
875 
876 // target ---------------------------------------------------------------------
877 
878 const char kTarget[] = "target";
879 const char kTarget_HelpShort[] =
880     "target: Declare a target with the given programmatic type.";
881 const char kTarget_Help[] =
882     R"(target: Declare a target with the given programmatic type.
883 
884   target(target_type_string, target_name_string) { ... }
885 
886   The target() function is a way to invoke a built-in target or template with a
887   type determined at runtime. This is useful for cases where the type of a
888   target might not be known statically.
889 
890   Only templates and built-in target functions are supported for the
891   target_type_string parameter. Arbitrary functions, configs, and toolchains
892   are not supported.
893 
894   The call:
895     target("source_set", "doom_melon") {
896   Is equivalent to:
897     source_set("doom_melon") {
898 
899 Common target variables
900 
901 )" DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
902 
903     R"(
904   Targets will also have variables specific to that type, see "gn help <type>"
905   for more.
906 
907 Example
908 
909   if (foo_build_as_shared) {
910     my_type = "shared_library"
911   } else {
912     my_type = "source_set"
913   }
914 
915   target(my_type, "foo") {
916     ...
917   }
918 )";
919 Value RunTarget(Scope* scope,
920                 const FunctionCallNode* function,
921                 const std::vector<Value>& args,
922                 BlockNode* block,
923                 Err* err) {
924   if (args.size() != 2) {
925     *err = Err(function, "Expected two arguments.", "Try \"gn help target\".");
926     return Value();
927   }
928 
929   // The first argument must be a string (the target type). Don't type-check
930   // the second argument since the target-specific function will do that.
931   if (!args[0].VerifyTypeIs(Value::STRING, err))
932     return Value();
933   const std::string& target_type = args[0].string_value();
934 
935   // The rest of the args are passed to the function.
936   std::vector<Value> sub_args(args.begin() + 1, args.end());
937 
938   // Run a template if it is one.
939   const Template* templ = scope->GetTemplate(target_type);
940   if (templ)
941     return templ->Invoke(scope, function, target_type, sub_args, block, err);
942 
943   // Otherwise, assume the target is a built-in target type.
944   return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args,
945                               block, err);
946 }
947 
948 const char kGeneratedFile[] = "generated_file";
949 const char kGeneratedFile_HelpShort[] =
950     "generated_file: Declare a generated_file target.";
951 const char kGeneratedFile_Help[] =
952     R"(generated_file: Declare a generated_file target.
953 
954   Writes data value(s) to disk on resolution. This target type mirrors some
955   functionality of the write_file() function, but also provides the ability to
956   collect metadata from its dependencies on resolution rather than writing out
957   at parse time.
958 
959   The `outputs` variable is required to be a list with a single element,
960   specifying the intended location of the output file.
961 
962   The `output_conversion` variable specified the format to write the
963   value. See `gn help io_conversion`.
964 
965   One of `contents` or `data_keys` must be specified; use of `contents` will
966   write the contents of that value to file, while use of `data_keys` will
967   trigger a metadata collection walk based on the dependencies of the target and
968   the optional values of the `rebase` and `walk_keys` variables. See
969   `gn help metadata`.
970 
971   Collected metadata, if specified, will be returned in postorder of
972   dependencies. See the example for details.
973 
974 Variables
975 
976 )" DEPENDENT_CONFIG_VARS DEPS_VARS GENERAL_TARGET_VARS
977 
978     R"(  Generated file: contents, data_keys, rebase, walk_keys, output_conversion
979 
980 Example (metadata collection)
981 
982   Given the following targets defined in //base/BUILD.gn, where A depends on B
983   and B depends on C and D:
984 
985     group("a") {
986       metadata = {
987         doom_melon = [ "enable" ]
988         my_files = [ "foo.cpp" ]
989 
990         # Note: this is functionally equivalent to not defining `my_barrier`
991         # at all in this target's metadata.
992         my_barrier = [ "" ]
993       }
994 
995       deps = [ ":b" ]
996     }
997 
998     group("b") {
999       metadata = {
1000         my_files = [ "bar.cpp" ]
1001         my_barrier = [ ":c" ]
1002       }
1003 
1004       deps = [ ":c", ":d" ]
1005     }
1006 
1007     group("c") {
1008       metadata = {
1009         doom_melon = [ "disable" ]
1010         my_files = [ "baz.cpp" ]
1011       }
1012     }
1013 
1014     group("d") {
1015       metadata = {
1016         my_files = [ "missing.cpp" ]
1017       }
1018     }
1019 
1020   If the following generated_file target is defined:
1021 
1022     generated_file("my_files_metadata") {
1023       outputs = [ "$root_build_dir/my_files.json" ]
1024       data_keys = [ "my_files" ]
1025 
1026       deps = [ "//base:a" ]
1027     }
1028 
1029   The following will be written to "$root_build_dir/my_files.json" (less the
1030   comments):
1031     [
1032       "baz.cpp",  // from //base:c via //base:b
1033       "missing.cpp"  // from //base:d via //base:b
1034       "bar.cpp",  // from //base:b via //base:a
1035       "foo.cpp",  // from //base:a
1036     ]
1037 
1038   Alternatively, as an example of using walk_keys, if the following
1039   generated_file target is defined:
1040 
1041   generated_file("my_files_metadata") {
1042     outputs = [ "$root_build_dir/my_files.json" ]
1043     data_keys = [ "my_files" ]
1044     walk_keys = [ "my_barrier" ]
1045 
1046     deps = [ "//base:a" ]
1047   }
1048 
1049   The following will be written to "$root_build_dir/my_files.json" (again less
1050   the comments):
1051     [
1052       "baz.cpp",  // from //base:c via //base:b
1053       "bar.cpp",  // from //base:b via //base:a
1054       "foo.cpp",  // from //base:a
1055     ]
1056 
1057   If `rebase` is used in the following generated_file target:
1058 
1059   generated_file("my_files_metadata") {
1060     outputs = [ "$root_build_dir/my_files.json" ]
1061     data_keys = [ "my_files" ]
1062     walk_keys = [ "my_barrier" ]
1063     rebase = root_build_dir
1064 
1065     deps = [ "//base:a" ]
1066   }
1067 
1068   The following will be written to "$root_build_dir/my_files.json" (again less
1069   the comments) (assuming root_build_dir = "//out"):
1070     [
1071       "../base/baz.cpp",  // from //base:c via //base:b
1072       "../base/bar.cpp",  // from //base:b via //base:a
1073       "../base/foo.cpp",  // from //base:a
1074     ]
1075 )";
1076 
RunGeneratedFile(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)1077 Value RunGeneratedFile(Scope* scope,
1078                        const FunctionCallNode* function,
1079                        const std::vector<Value>& args,
1080                        BlockNode* block,
1081                        Err* err) {
1082   return ExecuteGenericTarget(functions::kGeneratedFile, scope, function, args,
1083                               block, err);
1084 }
1085 
1086 }  // namespace functions
1087