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