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