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