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