• 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 
RunCopy(const FunctionCallNode * function,const std::vector<Value> & args,Scope * scope,Err * err)548 Value RunCopy(const FunctionCallNode* function,
549               const std::vector<Value>& args,
550               Scope* scope,
551               Err* err) {
552   if (!EnsureNotProcessingImport(function, scope, err) ||
553       !EnsureNotProcessingBuildConfig(function, scope, err))
554     return Value();
555   TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err);
556   return Value();
557 }
558 
559 // executable ------------------------------------------------------------------
560 
561 const char kExecutable[] = "executable";
562 const char kExecutable_HelpShort[] =
563     "executable: Declare an executable target.";
564 const char kExecutable_Help[] =
565     R"(executable: Declare an executable target.
566 
567 Language and compilation
568 )" LANGUAGE_HELP
569     R"(
570 
571 Variables
572 
573 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
574         RUST_VARS;
575 
576 Value RunExecutable(Scope* scope,
577                     const FunctionCallNode* function,
578                     const std::vector<Value>& args,
579                     BlockNode* block,
580                     Err* err) {
581   return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
582                               block, err);
583 }
584 
585 // group -----------------------------------------------------------------------
586 
587 const char kGroup[] = "group";
588 const char kGroup_HelpShort[] = "group: Declare a named group of targets.";
589 const char kGroup_Help[] =
590     R"(group: Declare a named group of targets.
591 
592   This target type allows you to create meta-targets that just collect a set of
593   dependencies into one named target. Groups can additionally specify configs
594   that apply to their dependents.
595 
596 Variables
597 
598 )" DEPS_VARS DEPENDENT_CONFIG_VARS
599 
600     R"(
601 Example
602 
603   group("all") {
604     deps = [
605       "//project:runner",
606       "//project:unit_tests",
607     ]
608   }
609 )";
610 
RunGroup(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)611 Value RunGroup(Scope* scope,
612                const FunctionCallNode* function,
613                const std::vector<Value>& args,
614                BlockNode* block,
615                Err* err) {
616   return ExecuteGenericTarget(functions::kGroup, scope, function, args, block,
617                               err);
618 }
619 
620 // loadable_module -------------------------------------------------------------
621 
622 const char kLoadableModule[] = "loadable_module";
623 const char kLoadableModule_HelpShort[] =
624     "loadable_module: Declare a loadable module target.";
625 const char kLoadableModule_Help[] =
626     R"(loadable_module: Declare a loadable module target.
627 
628   This target type allows you to create an object file that is (and can only
629   be) loaded and unloaded at runtime.
630 
631   A loadable module will be specified on the linker line for targets listing
632   the loadable module in its "deps". If you don't want this (if you don't need
633   to dynamically load the library at runtime), then you should use a
634   "shared_library" target type instead.
635 
636 Language and compilation
637 )" LANGUAGE_HELP
638     R"(
639 
640 Variables
641 
642 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
643         RUST_SHARED_VARS;
644 
645 Value RunLoadableModule(Scope* scope,
646                         const FunctionCallNode* function,
647                         const std::vector<Value>& args,
648                         BlockNode* block,
649                         Err* err) {
650   return ExecuteGenericTarget(functions::kLoadableModule, scope, function, args,
651                               block, err);
652 }
653 
654 // rust_library ----------------------------------------------------------------
655 
656 const char kRustLibrary[] = "rust_library";
657 const char kRustLibrary_HelpShort[] =
658     "rust_library: Declare a Rust library target.";
659 const char kRustLibrary_Help[] =
660     R"(rust_library: Declare a Rust library target.
661 
662   A Rust library is an archive containing additional rust-c provided metadata.
663   These are the files produced by the rustc compiler with the `.rlib`
664   extension, and are the intermediate step for most Rust-based binaries.
665 
666 Language and compilation
667 )" LANGUAGE_HELP
668     R"(
669 
670 Variables
671 
672 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
673         RUST_VARS;
674 Value RunRustLibrary(Scope* scope,
675                      const FunctionCallNode* function,
676                      const std::vector<Value>& args,
677                      BlockNode* block,
678                      Err* err) {
679   return ExecuteGenericTarget(functions::kRustLibrary, scope, function, args,
680                               block, err);
681 }
682 
683 // rust_proc_macro ----------------------------------------------------------------
684 
685 const char kRustProcMacro[] = "rust_proc_macro";
686 const char kRustProcMacro_HelpShort[] =
687     "rust_proc_macro: Declare a Rust procedural macro target.";
688 const char kRustProcMacro_Help[] =
689     R"(rust_proc_macro: Declare a Rust procedural macro target.
690 
691   A Rust procedural macro allows creating syntax extensions as execution of a
692   function. They are compiled as dynamic libraries and used by the compiler at
693   runtime.
694 
695   Their use is the same as of other Rust libraries, but their build has some
696   additional restrictions in terms of supported flags.
697 
698 Language and compilation
699 )" LANGUAGE_HELP
700     R"(
701 
702 Variables
703 
704 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
705         RUST_VARS;
706 Value RunRustProcMacro(Scope* scope,
707                    const FunctionCallNode* function,
708                    const std::vector<Value>& args,
709                    BlockNode* block,
710                    Err* err) {
711   return ExecuteGenericTarget(functions::kRustProcMacro, scope, function, args,
712                               block, err);
713 }
714 
715 // shared_library --------------------------------------------------------------
716 
717 const char kSharedLibrary[] = "shared_library";
718 const char kSharedLibrary_HelpShort[] =
719     "shared_library: Declare a shared library target.";
720 const char kSharedLibrary_Help[] =
721     R"(shared_library: Declare a shared library target.
722 
723   A shared library will be specified on the linker line for targets listing the
724   shared library in its "deps". If you don't want this (say you dynamically
725   load the library at runtime), then you should depend on the shared library
726   via "data_deps" or, on Darwin platforms, use a "loadable_module" target type
727   instead.
728 
729 Language and compilation
730 )" LANGUAGE_HELP
731     R"(
732 
733 Variables
734 
735 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
736         RUST_SHARED_VARS;
737 
738 Value RunSharedLibrary(Scope* scope,
739                        const FunctionCallNode* function,
740                        const std::vector<Value>& args,
741                        BlockNode* block,
742                        Err* err) {
743   return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args,
744                               block, err);
745 }
746 
747 // source_set ------------------------------------------------------------------
748 
749 const char kSourceSet[] = "source_set";
750 const char kSourceSet_HelpShort[] = "source_set: Declare a source set target.";
751 const char kSourceSet_Help[] =
752     R"(source_set: Declare a source set target.
753 
754   Only C-language source sets are supported at the moment.
755 
756 C-language source_sets
757 
758   A source set is a collection of sources that get compiled, but are not linked
759   to produce any kind of library. Instead, the resulting object files are
760   implicitly added to the linker line of all targets that depend on the source
761   set.
762 
763   In most cases, a source set will behave like a static library, except no
764   actual library file will be produced. This will make the build go a little
765   faster by skipping creation of a large static library, while maintaining the
766   organizational benefits of focused build targets.
767 
768   The main difference between a source set and a static library is around
769   handling of exported symbols. Most linkers assume declaring a function
770   exported means exported from the static library. The linker can then do dead
771   code elimination to delete code not reachable from exported functions.
772 
773   A source set will not do this code elimination since there is no link step.
774   This allows you to link many source sets into a shared library and have the
775   "exported symbol" notation indicate "export from the final shared library and
776   not from the intermediate targets." There is no way to express this concept
777   when linking multiple static libraries into a shared library.
778 
779 Variables
780 
781 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS;
782 
783 Value RunSourceSet(Scope* scope,
784                    const FunctionCallNode* function,
785                    const std::vector<Value>& args,
786                    BlockNode* block,
787                    Err* err) {
788   return ExecuteGenericTarget(functions::kSourceSet, scope, function, args,
789                               block, err);
790 }
791 
792 // static_library --------------------------------------------------------------
793 
794 const char kStaticLibrary[] = "static_library";
795 const char kStaticLibrary_HelpShort[] =
796     "static_library: Declare a static library target.";
797 const char kStaticLibrary_Help[] =
798     R"(static_library: Declare a static library target.
799 
800   Make a ".a" / ".lib" file.
801 
802   If you only need the static library for intermediate results in the build,
803   you should consider a source_set instead since it will skip the (potentially
804   slow) step of creating the intermediate library file.
805 
806 Variables
807 
808   complete_static_lib
809 )" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
810         RUST_VARS LANGUAGE_HELP;
811 
812 Value RunStaticLibrary(Scope* scope,
813                        const FunctionCallNode* function,
814                        const std::vector<Value>& args,
815                        BlockNode* block,
816                        Err* err) {
817   return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args,
818                               block, err);
819 }
820 
821 // target ---------------------------------------------------------------------
822 
823 const char kTarget[] = "target";
824 const char kTarget_HelpShort[] =
825     "target: Declare an target with the given programmatic type.";
826 const char kTarget_Help[] =
827     R"(target: Declare an target with the given programmatic type.
828 
829   target(target_type_string, target_name_string) { ... }
830 
831   The target() function is a way to invoke a built-in target or template with a
832   type determined at runtime. This is useful for cases where the type of a
833   target might not be known statically.
834 
835   Only templates and built-in target functions are supported for the
836   target_type_string parameter. Arbitrary functions, configs, and toolchains
837   are not supported.
838 
839   The call:
840     target("source_set", "doom_melon") {
841   Is equivalent to:
842     source_set("doom_melon") {
843 
844 Example
845 
846   if (foo_build_as_shared) {
847     my_type = "shared_library"
848   } else {
849     my_type = "source_set"
850   }
851 
852   target(my_type, "foo") {
853     ...
854   }
855 )";
856 Value RunTarget(Scope* scope,
857                 const FunctionCallNode* function,
858                 const std::vector<Value>& args,
859                 BlockNode* block,
860                 Err* err) {
861   if (args.size() != 2) {
862     *err = Err(function, "Expected two arguments.", "Try \"gn help target\".");
863     return Value();
864   }
865 
866   // The first argument must be a string (the target type). Don't type-check
867   // the second argument since the target-specific function will do that.
868   if (!args[0].VerifyTypeIs(Value::STRING, err))
869     return Value();
870   const std::string& target_type = args[0].string_value();
871 
872   // The rest of the args are passed to the function.
873   std::vector<Value> sub_args(args.begin() + 1, args.end());
874 
875   // Run a template if it is one.
876   const Template* templ = scope->GetTemplate(target_type);
877   if (templ)
878     return templ->Invoke(scope, function, target_type, sub_args, block, err);
879 
880   // Otherwise, assume the target is a built-in target type.
881   return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args,
882                               block, err);
883 }
884 
885 const char kGeneratedFile[] = "generated_file";
886 const char kGeneratedFile_HelpShort[] =
887     "generated_file: Declare a generated_file target.";
888 const char kGeneratedFile_Help[] =
889     R"(generated_file: Declare a generated_file target.
890 
891   Writes data value(s) to disk on resolution. This target type mirrors some
892   functionality of the write_file() function, but also provides the ability to
893   collect metadata from its dependencies on resolution rather than writing out
894   at parse time.
895 
896   The `outputs` variable is required to be a list with a single element,
897   specifying the intended location of the output file.
898 
899   The `output_conversion` variable specified the format to write the
900   value. See `gn help io_conversion`.
901 
902   One of `contents` or `data_keys` must be specified; use of `contents` will
903   write the contents of that value to file, while use of `data_keys` will
904   trigger a metadata collection walk based on the dependencies of the target and
905   the optional values of the `rebase` and `walk_keys` variables. See
906   `gn help metadata`.
907 
908   Collected metadata, if specified, will be returned in postorder of
909   dependencies. See the example for details.
910 
911 Example (metadata collection)
912 
913   Given the following targets defined in //base/BUILD.gn, where A depends on B
914   and B depends on C and D:
915 
916     group("a") {
917       metadata = {
918         doom_melon = [ "enable" ]
919         my_files = [ "foo.cpp" ]
920 
921         # Note: this is functionally equivalent to not defining `my_barrier`
922         # at all in this target's metadata.
923         my_barrier = [ "" ]
924       }
925 
926       deps = [ ":b" ]
927     }
928 
929     group("b") {
930       metadata = {
931         my_files = [ "bar.cpp" ]
932         my_barrier = [ ":c" ]
933       }
934 
935       deps = [ ":c", ":d" ]
936     }
937 
938     group("c") {
939       metadata = {
940         doom_melon = [ "disable" ]
941         my_files = [ "baz.cpp" ]
942       }
943     }
944 
945     group("d") {
946       metadata = {
947         my_files = [ "missing.cpp" ]
948       }
949     }
950 
951   If the following generated_file target is defined:
952 
953     generated_file("my_files_metadata") {
954       outputs = [ "$root_build_dir/my_files.json" ]
955       data_keys = [ "my_files" ]
956 
957       deps = [ "//base:a" ]
958     }
959 
960   The following will be written to "$root_build_dir/my_files.json" (less the
961   comments):
962     [
963       "baz.cpp",  // from //base:c via //base:b
964       "missing.cpp"  // from //base:d via //base:b
965       "bar.cpp",  // from //base:b via //base:a
966       "foo.cpp",  // from //base:a
967     ]
968 
969   Alternatively, as an example of using walk_keys, if the following
970   generated_file target is defined:
971 
972   generated_file("my_files_metadata") {
973     outputs = [ "$root_build_dir/my_files.json" ]
974     data_keys = [ "my_files" ]
975     walk_keys = [ "my_barrier" ]
976 
977     deps = [ "//base:a" ]
978   }
979 
980   The following will be written to "$root_build_dir/my_files.json" (again less
981   the comments):
982     [
983       "baz.cpp",  // from //base:c via //base:b
984       "bar.cpp",  // from //base:b via //base:a
985       "foo.cpp",  // from //base:a
986     ]
987 
988   If `rebase` is used in the following generated_file target:
989 
990   generated_file("my_files_metadata") {
991     outputs = [ "$root_build_dir/my_files.json" ]
992     data_keys = [ "my_files" ]
993     walk_keys = [ "my_barrier" ]
994     rebase = root_build_dir
995 
996     deps = [ "//base:a" ]
997   }
998 
999   The following will be written to "$root_build_dir/my_files.json" (again less
1000   the comments) (assuming root_build_dir = "//out"):
1001     [
1002       "../base/baz.cpp",  // from //base:c via //base:b
1003       "../base/bar.cpp",  // from //base:b via //base:a
1004       "../base/foo.cpp",  // from //base:a
1005     ]
1006 
1007 
1008 Variables
1009 
1010   contents
1011   data_keys
1012   rebase
1013   walk_keys
1014   output_conversion
1015 )" DEPS_VARS DEPENDENT_CONFIG_VARS;
1016 
RunGeneratedFile(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)1017 Value RunGeneratedFile(Scope* scope,
1018                        const FunctionCallNode* function,
1019                        const std::vector<Value>& args,
1020                        BlockNode* block,
1021                        Err* err) {
1022   return ExecuteGenericTarget(functions::kGeneratedFile, scope, function, args,
1023                               block, err);
1024 }
1025 
1026 }  // namespace functions
1027