[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / tools / gn / functions_target.cc
blob5c30fb9bc08c043103a1c86b426b124d682231a9
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.
5 #include "tools/gn/functions.h"
7 #include "tools/gn/config_values_generator.h"
8 #include "tools/gn/err.h"
9 #include "tools/gn/parse_tree.h"
10 #include "tools/gn/scope.h"
11 #include "tools/gn/target_generator.h"
12 #include "tools/gn/template.h"
13 #include "tools/gn/value.h"
14 #include "tools/gn/variables.h"
16 #define DEPENDENT_CONFIG_VARS \
17 " Dependent configs: all_dependent_configs, public_configs\n"
18 #define DEPS_VARS \
19 " Deps: data_deps, deps, forward_dependent_configs_from, public_deps\n"
20 #define GENERAL_TARGET_VARS \
21 " General: check_includes, configs, data, inputs, output_name,\n" \
22 " output_extension, public, sources, testonly, visibility\n"
24 namespace functions {
26 namespace {
28 Value ExecuteGenericTarget(const char* target_type,
29 Scope* scope,
30 const FunctionCallNode* function,
31 const std::vector<Value>& args,
32 BlockNode* block,
33 Err* err) {
34 NonNestableBlock non_nestable(scope, function, "target");
35 if (!non_nestable.Enter(err))
36 return Value();
38 if (!EnsureNotProcessingImport(function, scope, err) ||
39 !EnsureNotProcessingBuildConfig(function, scope, err))
40 return Value();
41 Scope block_scope(scope);
42 if (!FillTargetBlockScope(scope, function, target_type, block,
43 args, &block_scope, err))
44 return Value();
46 block->Execute(&block_scope, err);
47 if (err->has_error())
48 return Value();
50 TargetGenerator::GenerateTarget(&block_scope, function, args,
51 target_type, err);
52 if (err->has_error())
53 return Value();
55 block_scope.CheckForUnusedVars(err);
56 return Value();
59 } // namespace
61 // action ----------------------------------------------------------------------
63 // Common help paragraph on script runtime execution directories.
64 #define SCRIPT_EXECUTION_CONTEXT \
65 " The script will be executed with the given arguments with the current\n"\
66 " directory being that of the root build directory. If you pass files\n"\
67 " to your script, see \"gn help rebase_path\" for how to convert\n" \
68 " file names to be relative to the build directory (file names in the\n" \
69 " sources, outputs, and inputs will be all treated as relative to the\n" \
70 " current build file and converted as needed automatically).\n"
72 // Common help paragraph on script output directories.
73 #define SCRIPT_EXECUTION_OUTPUTS \
74 " All output files must be inside the output directory of the build.\n" \
75 " You would generally use |$target_out_dir| or |$target_gen_dir| to\n" \
76 " reference the output or generated intermediate file directories,\n" \
77 " respectively.\n"
79 #define ACTION_DEPS \
80 " The \"deps\" and \"public_deps\" for an action will always be\n" \
81 " completed before any part of the action is run so it can depend on\n" \
82 " the output of previous steps. The \"data_deps\" will be built if the\n" \
83 " action is built, but may not have completed before all steps of the\n" \
84 " action are started. This can give additional parallelism in the build\n"\
85 " for runtime-only dependencies.\n"
87 const char kAction[] = "action";
88 const char kAction_HelpShort[] =
89 "action: Declare a target that runs a script a single time.";
90 const char kAction_Help[] =
91 "action: Declare a target that runs a script a single time.\n"
92 "\n"
93 " This target type allows you to run a script a single time to produce\n"
94 " or more output files. If you want to run a script once for each of a\n"
95 " set of input files, see \"gn help action_foreach\".\n"
96 "\n"
97 "Inputs\n"
98 "\n"
99 " In an action the \"sources\" and \"inputs\" are treated the same:\n"
100 " they're both input dependencies on script execution with no special\n"
101 " handling. If you want to pass the sources to your script, you must do\n"
102 " so explicitly by including them in the \"args\". Note also that this\n"
103 " means there is no special handling of paths since GN doesn't know\n"
104 " which of the args are paths and not. You will want to use\n"
105 " rebase_path() to convert paths to be relative to the root_build_dir.\n"
106 "\n"
107 " You can dynamically write input dependencies (for incremental rebuilds\n"
108 " if an input file changes) by writing a depfile when the script is run\n"
109 " (see \"gn help depfile\"). This is more flexible than \"inputs\".\n"
110 "\n"
111 " It is recommended you put inputs to your script in the \"sources\"\n"
112 " variable, and stuff like other Python files required to run your\n"
113 " script in the \"inputs\" variable.\n"
114 "\n"
115 ACTION_DEPS
116 "\n"
117 "Outputs\n"
118 "\n"
119 " You should specify files created by your script by specifying them in\n"
120 " the \"outputs\".\n"
121 "\n"
122 SCRIPT_EXECUTION_CONTEXT
123 "\n"
124 "File name handling\n"
125 "\n"
126 SCRIPT_EXECUTION_OUTPUTS
127 "\n"
128 "Variables\n"
129 "\n"
130 " args, data, data_deps, depfile, deps, outputs*, script*,\n"
131 " inputs, sources\n"
132 " * = required\n"
133 "\n"
134 "Example\n"
135 "\n"
136 " action(\"run_this_guy_once\") {\n"
137 " script = \"doprocessing.py\"\n"
138 " sources = [ \"my_configuration.txt\" ]\n"
139 " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n"
140 "\n"
141 " # Our script imports this Python file so we want to rebuild if it\n"
142 " # changes.\n"
143 " inputs = [ \"helper_library.py\" ]\n"
144 "\n"
145 " # Note that we have to manually pass the sources to our script if\n"
146 " # the script needs them as inputs.\n"
147 " args = [ \"--out\", rebase_path(target_gen_dir, root_build_dir) ] +\n"
148 " rebase_path(sources, root_build_dir)\n"
149 " }\n";
151 Value RunAction(Scope* scope,
152 const FunctionCallNode* function,
153 const std::vector<Value>& args,
154 BlockNode* block,
155 Err* err) {
156 return ExecuteGenericTarget(functions::kAction, scope, function, args,
157 block, err);
160 // action_foreach --------------------------------------------------------------
162 const char kActionForEach[] = "action_foreach";
163 const char kActionForEach_HelpShort[] =
164 "action_foreach: Declare a target that runs a script over a set of files.";
165 const char kActionForEach_Help[] =
166 "action_foreach: Declare a target that runs a script over a set of files.\n"
167 "\n"
168 " This target type allows you to run a script once-per-file over a set\n"
169 " of sources. If you want to run a script once that takes many files as\n"
170 " input, see \"gn help action\".\n"
171 "\n"
172 "Inputs\n"
173 "\n"
174 " The script will be run once per file in the \"sources\" variable. The\n"
175 " \"outputs\" variable should specify one or more files with a source\n"
176 " expansion pattern in it (see \"gn help source_expansion\"). The output\n"
177 " file(s) for each script invocation should be unique. Normally you\n"
178 " use \"{{source_name_part}}\" in each output file.\n"
179 "\n"
180 " If your script takes additional data as input, such as a shared\n"
181 " configuration file or a Python module it uses, those files should be\n"
182 " listed in the \"inputs\" variable. These files are treated as\n"
183 " dependencies of each script invocation.\n"
184 "\n"
185 " You can dynamically write input dependencies (for incremental rebuilds\n"
186 " if an input file changes) by writing a depfile when the script is run\n"
187 " (see \"gn help depfile\"). This is more flexible than \"inputs\".\n"
188 "\n"
189 ACTION_DEPS
190 "\n"
191 "Outputs\n"
192 "\n"
193 SCRIPT_EXECUTION_CONTEXT
194 "\n"
195 "File name handling\n"
196 "\n"
197 SCRIPT_EXECUTION_OUTPUTS
198 "\n"
199 "Variables\n"
200 "\n"
201 " args, data, data_deps, depfile, deps, outputs*, script*,\n"
202 " inputs, sources*\n"
203 " * = required\n"
204 "\n"
205 "Example\n"
206 "\n"
207 " # Runs the script over each IDL file. The IDL script will generate\n"
208 " # both a .cc and a .h file for each input.\n"
209 " action_foreach(\"my_idl\") {\n"
210 " script = \"idl_processor.py\"\n"
211 " sources = [ \"foo.idl\", \"bar.idl\" ]\n"
212 "\n"
213 " # Our script reads this file each time, so we need to list is as a\n"
214 " # dependency so we can rebuild if it changes.\n"
215 " inputs = [ \"my_configuration.txt\" ]\n"
216 "\n"
217 " # Transformation from source file name to output file names.\n"
218 " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\",\n"
219 " \"$target_gen_dir/{{source_name_part}}.cc\" ]\n"
220 "\n"
221 " # Note that since \"args\" is opaque to GN, if you specify paths\n"
222 " # here, you will need to convert it to be relative to the build\n"
223 " # directory using \"rebase_path()\".\n"
224 " args = [\n"
225 " \"{{source}}\",\n"
226 " \"-o\",\n"
227 " rebase_path(relative_target_gen_dir, root_build_dir) +\n"
228 " \"/{{source_name_part}}.h\" ]\n"
229 " }\n"
230 "\n";
231 Value RunActionForEach(Scope* scope,
232 const FunctionCallNode* function,
233 const std::vector<Value>& args,
234 BlockNode* block,
235 Err* err) {
236 return ExecuteGenericTarget(functions::kActionForEach, scope, function, args,
237 block, err);
240 // copy ------------------------------------------------------------------------
242 const char kCopy[] = "copy";
243 const char kCopy_HelpShort[] =
244 "copy: Declare a target that copies files.";
245 const char kCopy_Help[] =
246 "copy: Declare a target that copies files.\n"
247 "\n"
248 "File name handling\n"
249 "\n"
250 " All output files must be inside the output directory of the build.\n"
251 " You would generally use |$target_out_dir| or |$target_gen_dir| to\n"
252 " reference the output or generated intermediate file directories,\n"
253 " respectively.\n"
254 "\n"
255 " Both \"sources\" and \"outputs\" must be specified. Sources can "
256 "include\n"
257 " as many files as you want, but there can only be one item in the\n"
258 " outputs list (plural is used for the name for consistency with\n"
259 " other target types).\n"
260 "\n"
261 " If there is more than one source file, your output name should specify\n"
262 " a mapping from each source file to an output file name using source\n"
263 " expansion (see \"gn help source_expansion\"). The placeholders will\n"
264 " look like \"{{source_name_part}}\", for example.\n"
265 "\n"
266 "Examples\n"
267 "\n"
268 " # Write a rule that copies a checked-in DLL to the output directory.\n"
269 " copy(\"mydll\") {\n"
270 " sources = [ \"mydll.dll\" ]\n"
271 " outputs = [ \"$target_out_dir/mydll.dll\" ]\n"
272 " }\n"
273 "\n"
274 " # Write a rule to copy several files to the target generated files\n"
275 " # directory.\n"
276 " copy(\"myfiles\") {\n"
277 " sources = [ \"data1.dat\", \"data2.dat\", \"data3.dat\" ]\n"
278 "\n"
279 " # Use source expansion to generate output files with the\n"
280 " # corresponding file names in the gen dir. This will just copy each\n"
281 " # file.\n"
282 " outputs = [ \"$target_gen_dir/{{source_file_part}}\" ]\n"
283 " }\n";
285 Value RunCopy(const FunctionCallNode* function,
286 const std::vector<Value>& args,
287 Scope* scope,
288 Err* err) {
289 if (!EnsureNotProcessingImport(function, scope, err) ||
290 !EnsureNotProcessingBuildConfig(function, scope, err))
291 return Value();
292 TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err);
293 return Value();
296 // executable ------------------------------------------------------------------
298 const char kExecutable[] = "executable";
299 const char kExecutable_HelpShort[] =
300 "executable: Declare an executable target.";
301 const char kExecutable_Help[] =
302 "executable: Declare an executable target.\n"
303 "\n"
304 "Variables\n"
305 "\n"
306 CONFIG_VALUES_VARS_HELP
307 DEPS_VARS
308 DEPENDENT_CONFIG_VARS
309 GENERAL_TARGET_VARS;
311 Value RunExecutable(Scope* scope,
312 const FunctionCallNode* function,
313 const std::vector<Value>& args,
314 BlockNode* block,
315 Err* err) {
316 return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
317 block, err);
320 // group -----------------------------------------------------------------------
322 const char kGroup[] = "group";
323 const char kGroup_HelpShort[] =
324 "group: Declare a named group of targets.";
325 const char kGroup_Help[] =
326 "group: Declare a named group of targets.\n"
327 "\n"
328 " This target type allows you to create meta-targets that just collect a\n"
329 " set of dependencies into one named target. Groups can additionally\n"
330 " specify configs that apply to their dependents.\n"
331 "\n"
332 " Depending on a group is exactly like depending directly on that\n"
333 " group's deps. Direct dependent configs will get automatically\n"
334 " forwarded through the group so you shouldn't need to use\n"
335 " \"forward_dependent_configs_from.\n"
336 "\n"
337 "Variables\n"
338 "\n"
339 DEPS_VARS
340 DEPENDENT_CONFIG_VARS
341 "\n"
342 "Example\n"
343 "\n"
344 " group(\"all\") {\n"
345 " deps = [\n"
346 " \"//project:runner\",\n"
347 " \"//project:unit_tests\",\n"
348 " ]\n"
349 " }\n";
351 Value RunGroup(Scope* scope,
352 const FunctionCallNode* function,
353 const std::vector<Value>& args,
354 BlockNode* block,
355 Err* err) {
356 return ExecuteGenericTarget(functions::kGroup, scope, function, args,
357 block, err);
360 // shared_library --------------------------------------------------------------
362 const char kSharedLibrary[] = "shared_library";
363 const char kSharedLibrary_HelpShort[] =
364 "shared_library: Declare a shared library target.";
365 const char kSharedLibrary_Help[] =
366 "shared_library: Declare a shared library target.\n"
367 "\n"
368 " A shared library will be specified on the linker line for targets\n"
369 " listing the shared library in its \"deps\". If you don't want this\n"
370 " (say you dynamically load the library at runtime), then you should\n"
371 " depend on the shared library via \"data_deps\" instead.\n"
372 "\n"
373 "Variables\n"
374 "\n"
375 CONFIG_VALUES_VARS_HELP
376 DEPS_VARS
377 DEPENDENT_CONFIG_VARS
378 GENERAL_TARGET_VARS;
380 Value RunSharedLibrary(Scope* scope,
381 const FunctionCallNode* function,
382 const std::vector<Value>& args,
383 BlockNode* block,
384 Err* err) {
385 return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args,
386 block, err);
389 // source_set ------------------------------------------------------------------
391 extern const char kSourceSet[] = "source_set";
392 extern const char kSourceSet_HelpShort[] =
393 "source_set: Declare a source set target.";
394 extern const char kSourceSet_Help[] =
395 "source_set: Declare a source set target.\n"
396 "\n"
397 " A source set is a collection of sources that get compiled, but are not\n"
398 " linked to produce any kind of library. Instead, the resulting object\n"
399 " files are implicitly added to the linker line of all targets that\n"
400 " depend on the source set.\n"
401 "\n"
402 " In most cases, a source set will behave like a static library, except\n"
403 " no actual library file will be produced. This will make the build go\n"
404 " a little faster by skipping creation of a large static library, while\n"
405 " maintaining the organizational benefits of focused build targets.\n"
406 "\n"
407 " The main difference between a source set and a static library is\n"
408 " around handling of exported symbols. Most linkers assume declaring\n"
409 " a function exported means exported from the static library. The linker\n"
410 " can then do dead code elimination to delete code not reachable from\n"
411 " exported functions.\n"
412 "\n"
413 " A source set will not do this code elimination since there is no link\n"
414 " step. This allows you to link many sources sets into a shared library\n"
415 " and have the \"exported symbol\" notation indicate \"export from the\n"
416 " final shared library and not from the intermediate targets.\" There is\n"
417 " no way to express this concept when linking multiple static libraries\n"
418 " into a shared library.\n"
419 "\n"
420 "Variables\n"
421 "\n"
422 CONFIG_VALUES_VARS_HELP
423 DEPS_VARS
424 DEPENDENT_CONFIG_VARS
425 GENERAL_TARGET_VARS;
427 Value RunSourceSet(Scope* scope,
428 const FunctionCallNode* function,
429 const std::vector<Value>& args,
430 BlockNode* block,
431 Err* err) {
432 return ExecuteGenericTarget(functions::kSourceSet, scope, function, args,
433 block, err);
436 // static_library --------------------------------------------------------------
438 const char kStaticLibrary[] = "static_library";
439 const char kStaticLibrary_HelpShort[] =
440 "static_library: Declare a static library target.";
441 const char kStaticLibrary_Help[] =
442 "static_library: Declare a static library target.\n"
443 "\n"
444 " Make a \".a\" / \".lib\" file.\n"
445 "\n"
446 " If you only need the static library for intermediate results in the\n"
447 " build, you should consider a source_set instead since it will skip\n"
448 " the (potentially slow) step of creating the intermediate library file.\n"
449 "\n"
450 "Variables\n"
451 "\n"
452 CONFIG_VALUES_VARS_HELP
453 DEPS_VARS
454 DEPENDENT_CONFIG_VARS
455 GENERAL_TARGET_VARS;
457 Value RunStaticLibrary(Scope* scope,
458 const FunctionCallNode* function,
459 const std::vector<Value>& args,
460 BlockNode* block,
461 Err* err) {
462 return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args,
463 block, err);
466 // target ---------------------------------------------------------------------
468 const char kTarget[] = "target";
469 const char kTarget_HelpShort[] =
470 "target: Declare an target with the given programmatic type.";
471 const char kTarget_Help[] =
472 "target: Declare an target with the given programmatic type.\n"
473 "\n"
474 " target(target_type_string, target_name_string) { ... }\n"
475 "\n"
476 " The target() function is a way to invoke a built-in target or template\n"
477 " with a type determined at runtime. This is useful for cases where the\n"
478 " type of a target might not be known statically.\n"
479 "\n"
480 " Only templates and built-in target functions are supported for the\n"
481 " target_type_string parameter. Arbitrary functions, configs, and\n"
482 " toolchains are not supported.\n"
483 "\n"
484 " The call:\n"
485 " target(\"source_set\", \"doom_melon\") {\n"
486 " Is equivalent to:\n"
487 " source_set(\"doom_melon\") {\n"
488 "\n"
489 "Example\n"
490 "\n"
491 " if (foo_build_as_shared) {\n"
492 " my_type = \"shared_library\"\n"
493 " } else {\n"
494 " my_type = \"source_set\"\n"
495 " }\n"
496 "\n"
497 " target(my_type, \"foo\") {\n"
498 " ...\n"
499 " }\n";
500 Value RunTarget(Scope* scope,
501 const FunctionCallNode* function,
502 const std::vector<Value>& args,
503 BlockNode* block,
504 Err* err) {
505 if (args.size() != 2) {
506 *err = Err(function, "Expected two arguments.",
507 "Dude, try \"gn help target\".");
508 return Value();
511 // The first argument must be a string (the target type). Don't type-check
512 // the second argument since the target-specific function will do that.
513 if (!args[0].VerifyTypeIs(Value::STRING, err))
514 return Value();
515 const std::string& target_type = args[0].string_value();
517 // The rest of the args are passed to the function.
518 std::vector<Value> sub_args(args.begin() + 1, args.end());
520 // Run a template if it is one.
521 const Template* templ = scope->GetTemplate(target_type);
522 if (templ)
523 return templ->Invoke(scope, function, sub_args, block, err);
525 // Otherwise, assume the target is a built-in target type.
526 return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args,
527 block, err);
530 } // namespace functions