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