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