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