Replace command buffer FlushSync with WaitForTokenInRange and WaitForGetOffsetInRange
[chromium-blink-merge.git] / tools / gn / functions_target.cc
blob8c61f3b43b745fcc68d86d7eccaeb5f08dfbcc95
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/value.h"
13 #include "tools/gn/variables.h"
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, external, source_prereqs, sources\n"
22 namespace functions {
24 namespace {
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();
40 block->ExecuteBlockInScope(&block_scope, err);
41 if (err->has_error())
42 return Value();
44 TargetGenerator::GenerateTarget(&block_scope, function, args,
45 target_type, err);
46 if (err->has_error())
47 return Value();
49 block_scope.CheckForUnusedVars(err);
50 return Value();
53 } // namespace
55 // component -------------------------------------------------------------------
57 const char kComponent[] = "component";
58 const char kComponent_Help[] =
59 "component: Declare a component target.\n"
60 "\n"
61 " A component is a shared library, static library, or source set\n"
62 " depending on the component mode. This allows a project to separate\n"
63 " out a build into shared libraries for faster development (link time is\n"
64 " reduced) but to switch to a static build for releases (for better\n"
65 " performance).\n"
66 "\n"
67 " To use this function you must set the value of the \"component_mode\"\n"
68 " variable to one of the following strings:\n"
69 " - \"shared_library\"\n"
70 " - \"static_library\"\n"
71 " - \"source_set\"\n"
72 " It is an error to call \"component\" without defining the mode\n"
73 " (typically this is done in the master build configuration file).\n";
75 Value RunComponent(Scope* scope,
76 const FunctionCallNode* function,
77 const std::vector<Value>& args,
78 BlockNode* block,
79 Err* err) {
80 // A component is either a shared or static library, depending on the value
81 // of |component_mode|.
82 const Value* component_mode_value =
83 scope->GetValue(variables::kComponentMode);
85 static const char helptext[] =
86 "You're declaring a component here but have not defined "
87 "\"component_mode\" to\neither \"shared_library\" or \"static_library\".";
88 if (!component_mode_value) {
89 *err = Err(function->function(), "No component mode set.", helptext);
90 return Value();
92 if (component_mode_value->type() != Value::STRING ||
93 (component_mode_value->string_value() != functions::kSharedLibrary &&
94 component_mode_value->string_value() != functions::kStaticLibrary &&
95 component_mode_value->string_value() != functions::kSourceSet)) {
96 *err = Err(function->function(), "Invalid component mode set.", helptext);
97 return Value();
99 const std::string& component_mode = component_mode_value->string_value();
101 if (!EnsureNotProcessingImport(function, scope, err))
102 return Value();
103 Scope block_scope(scope);
104 if (!FillTargetBlockScope(scope, function, component_mode.c_str(), block,
105 args, &block_scope, err))
106 return Value();
108 block->ExecuteBlockInScope(&block_scope, err);
109 if (err->has_error())
110 return Value();
112 TargetGenerator::GenerateTarget(&block_scope, function, args,
113 component_mode, err);
114 return Value();
117 // copy ------------------------------------------------------------------------
119 const char kCopy[] = "copy";
120 const char kCopy_Help[] =
121 "copy: Declare a target that copies files.\n"
122 "\n"
123 "File name handling\n"
124 "\n"
125 " All output files must be inside the output directory of the build.\n"
126 " You would generally use |$target_out_dir| or |$target_gen_dir| to\n"
127 " reference the output or generated intermediate file directories,\n"
128 " respectively.\n"
129 "\n"
130 " Both \"sources\" and \"outputs\" must be specified. Sources can\n"
131 " as many files as you want, but there can only be one item in the\n"
132 " outputs list (plural is used for the name for consistency with\n"
133 " other target types).\n"
134 "\n"
135 " If there is more than one source file, your output name should specify\n"
136 " a mapping from each source files to output file names using source\n"
137 " expansion (see \"gn help source_expansion\"). The placeholders will\n"
138 " will look like \"{{source_name_part}}\", for example.\n"
139 "\n"
140 "Examples\n"
141 "\n"
142 " # Write a rule that copies a checked-in DLL to the output directory.\n"
143 " copy(\"mydll\") {\n"
144 " sources = [ \"mydll.dll\" ]\n"
145 " outputs = [ \"$target_out_dir/mydll.dll\" ]\n"
146 " }\n"
147 "\n"
148 " # Write a rule to copy several files to the target generated files\n"
149 " # directory.\n"
150 " copy(\"myfiles\") {\n"
151 " sources = [ \"data1.dat\", \"data2.dat\", \"data3.dat\" ]\n"
152 "\n"
153 " # Use source expansion to generate output files with the\n"
154 " # corresponding file names in the gen dir. This will just copy each\n"
155 " # file.\n"
156 " outputs = [ \"$target_gen_dir/{{source_file_part}}\" ]\n"
157 " }\n";
159 Value RunCopy(const FunctionCallNode* function,
160 const std::vector<Value>& args,
161 Scope* scope,
162 Err* err) {
163 if (!EnsureNotProcessingImport(function, scope, err) ||
164 !EnsureNotProcessingBuildConfig(function, scope, err))
165 return Value();
166 TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err);
167 return Value();
170 // custom ----------------------------------------------------------------------
172 const char kCustom[] = "custom";
173 const char kCustom_Help[] =
174 "custom: Declare a script-generated target.\n"
175 "\n"
176 " This target type allows you to run a script over a set of source\n"
177 " files and generate a set of output files.\n"
178 "\n"
179 " The script will be executed with the given arguments with the current\n"
180 " directory being that of the root build directory. If you pass files\n"
181 " to your script, see \"gn help to_build_path\" for how to convert\n"
182 " file names to be relative to the build directory (file names in the\n"
183 " sources, outputs, and source_prereqs will be all treated as relative\n"
184 " to the current build file and converted as needed automatically).\n"
185 "\n"
186 " There are two modes. The first mode is the \"per-file\" mode where you\n"
187 " specify a list of sources and the script is run once for each one as a\n"
188 " build rule. In this case, each file specified in the |outputs|\n"
189 " variable must be unique when applied to each source file (normally you\n"
190 " would reference |{{source_name_part}}| from within each one) or the\n"
191 " build system will get confused about how to build those files. You\n"
192 " should use the |source_prereqs| variable to list all additional\n"
193 " dependencies of your script: these will be added as dependencies for\n"
194 " each build step.\n"
195 "\n"
196 " The second mode is when you just want to run a script once rather than\n"
197 " as a general rule over a set of files. In this case you don't list any\n"
198 " sources. Dependencies of your script are specified only in the\n"
199 " |source_prereqs| variable and your |outputs| variable should just list\n"
200 " all outputs.\n"
201 "\n"
202 "File name handling\n"
203 "\n"
204 " All output files must be inside the output directory of the build.\n"
205 " You would generally use |$target_out_dir| or |$target_gen_dir| to\n"
206 " reference the output or generated intermediate file directories,\n"
207 " respectively.\n"
208 "\n"
209 " You can specify a mapping from source files to output files using\n"
210 " source expansion (see \"gn help source_expansion\"). The placeholders\n"
211 " will look like \"{{source}}\", for example, and can appear in\n"
212 " either the outputs or the args lists.\n"
213 "\n"
214 "Variables\n"
215 "\n"
216 " args, deps, outputs, script*, source_prereqs, sources\n"
217 " * = required\n"
218 "\n"
219 "Examples\n"
220 "\n"
221 " # Runs the script over each IDL file. The IDL script will generate\n"
222 " # both a .cc and a .h file for each input.\n"
223 " custom(\"general_rule\") {\n"
224 " script = \"idl_processor.py\"\n"
225 " sources = [ \"foo.idl\", \"bar.idl\" ]\n"
226 " source_prereqs = [ \"my_configuration.txt\" ]\n"
227 " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\",\n"
228 " \"$target_gen_dir/{{source_name_part}}.cc\" ]\n"
229 "\n"
230 " # Note that since \"args\" is opaque to GN, if you specify paths\n"
231 " # here, you will need to convert it to be relative to the build\n"
232 " # directory using \"to_build_path()\".\n"
233 " args = [ \"{{source}}\",\n"
234 " \"-o\",\n"
235 " to_build_path(relative_target_gen_dir) + \"/\" +\n"
236 " {{source_name_part}}.h\" ]\n"
237 " }\n"
238 "\n"
239 " custom(\"just_run_this_guy_once\") {\n"
240 " script = \"doprocessing.py\"\n"
241 " source_prereqs = [ \"my_configuration.txt\" ]\n"
242 " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n"
243 " args = [ \"--output_dir\", to_build_path(target_gen_dir) ]\n"
244 " }\n";
246 Value RunCustom(Scope* scope,
247 const FunctionCallNode* function,
248 const std::vector<Value>& args,
249 BlockNode* block,
250 Err* err) {
251 return ExecuteGenericTarget(functions::kCustom, scope, function, args,
252 block, err);
255 // executable ------------------------------------------------------------------
257 const char kExecutable[] = "executable";
258 const char kExecutable_Help[] =
259 "executable: Declare an executable target.\n"
260 "\n"
261 "Variables\n"
262 "\n"
263 CONFIG_VALUES_VARS_HELP
264 DEPS_VARS
265 DEPENDENT_CONFIG_VARS
266 GENERAL_TARGET_VARS;
268 Value RunExecutable(Scope* scope,
269 const FunctionCallNode* function,
270 const std::vector<Value>& args,
271 BlockNode* block,
272 Err* err) {
273 return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
274 block, err);
277 // group -----------------------------------------------------------------------
279 const char kGroup[] = "group";
280 const char kGroup_Help[] =
281 "group: Declare a named group of targets.\n"
282 "\n"
283 " This target type allows you to create meta-targets that just collect a\n"
284 " set of dependencies into one named target. Groups can additionally\n"
285 " specify configs that apply to their dependents.\n"
286 "\n"
287 " Depending on a group is exactly like depending directly on that\n"
288 " group's deps. Direct dependent configs will get automatically\n"
289 " forwarded through the group so you shouldn't need to use\n"
290 " \"forward_dependent_configs_from.\n"
291 "\n"
292 "Variables\n"
293 "\n"
294 DEPS_VARS
295 DEPENDENT_CONFIG_VARS
296 " Other variables: external\n"
297 "\n"
298 "Example\n"
299 "\n"
300 " group(\"all\") {\n"
301 " deps = [\n"
302 " \"//project:runner\",\n"
303 " \"//project:unit_tests\",\n"
304 " ]\n"
305 " }\n";
307 Value RunGroup(Scope* scope,
308 const FunctionCallNode* function,
309 const std::vector<Value>& args,
310 BlockNode* block,
311 Err* err) {
312 return ExecuteGenericTarget(functions::kGroup, scope, function, args,
313 block, err);
316 // shared_library --------------------------------------------------------------
318 const char kSharedLibrary[] = "shared_library";
319 const char kSharedLibrary_Help[] =
320 "shared_library: Declare a shared library target.\n"
321 "\n"
322 " A shared library will be specified on the linker line for targets\n"
323 " listing the shared library in its \"deps\". If you don't want this\n"
324 " (say you dynamically load the library at runtime), then you should\n"
325 " depend on the shared library via \"datadeps\" instead.\n"
326 "\n"
327 "Variables\n"
328 "\n"
329 CONFIG_VALUES_VARS_HELP
330 DEPS_VARS
331 DEPENDENT_CONFIG_VARS
332 GENERAL_TARGET_VARS;
334 Value RunSharedLibrary(Scope* scope,
335 const FunctionCallNode* function,
336 const std::vector<Value>& args,
337 BlockNode* block,
338 Err* err) {
339 return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args,
340 block, err);
343 // source_set ------------------------------------------------------------------
345 extern const char kSourceSet[] = "source_set";
346 extern const char kSourceSet_Help[] =
347 "source_set: Declare a source set target.\n"
348 "\n"
349 " A source set is a collection of sources that get compiled, but are not\n"
350 " linked to produce any kind of library. Instead, the resulting object\n"
351 " files are implicitly added to the linker line of all targets that\n"
352 " depend on the source set.\n"
353 "\n"
354 " In most cases, a source set will behave like a static library, except\n"
355 " no actual library file will be produced. This will make the build go\n"
356 " a little faster by skipping creation of a large static library, while\n"
357 " maintaining the organizational benefits of focused build targets.\n"
358 "\n"
359 " The main difference between a source set and a static library is\n"
360 " around handling of exported symbols. Most linkers assume declaring\n"
361 " a function exported means exported from the static library. The linker\n"
362 " can then do dead code elimination to delete code not reachable from\n"
363 " exported functions.\n"
364 "\n"
365 " A source set will not do this code elimination since there is no link\n"
366 " step. This allows you to link many sources sets into a shared library\n"
367 " and have the \"exported symbol\" notation indicate \"export from the\n"
368 " final shared library and not from the intermediate targets.\" There is\n"
369 " no way to express this concept when linking multiple static libraries\n"
370 " into a shared library.\n"
371 "\n"
372 "Variables\n"
373 "\n"
374 CONFIG_VALUES_VARS_HELP
375 DEPS_VARS
376 DEPENDENT_CONFIG_VARS
377 GENERAL_TARGET_VARS;
379 Value RunSourceSet(Scope* scope,
380 const FunctionCallNode* function,
381 const std::vector<Value>& args,
382 BlockNode* block,
383 Err* err) {
384 return ExecuteGenericTarget(functions::kSourceSet, scope, function, args,
385 block, err);
388 // static_library --------------------------------------------------------------
390 const char kStaticLibrary[] = "static_library";
391 const char kStaticLibrary_Help[] =
392 "static_library: Declare a static library target.\n"
393 "\n"
394 " Make a \".a\" / \".lib\" file.\n"
395 "\n"
396 " If you only need the static library for intermediate results in the\n"
397 " build, you should consider a source_set instead since it will skip\n"
398 " the (potentially slow) step of creating the intermediate library file.\n"
399 "\n"
400 "Variables\n"
401 "\n"
402 CONFIG_VALUES_VARS_HELP
403 DEPS_VARS
404 DEPENDENT_CONFIG_VARS
405 GENERAL_TARGET_VARS;
407 Value RunStaticLibrary(Scope* scope,
408 const FunctionCallNode* function,
409 const std::vector<Value>& args,
410 BlockNode* block,
411 Err* err) {
412 return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args,
413 block, err);
416 // test ------------------------------------------------------------------------
418 const char kTest[] = "test";
419 const char kTest_Help[] =
420 "test: Declares a test target.\n"
421 "\n"
422 " This is like an executable target, but is named differently to make\n"
423 " the purpose of the target more obvious. It's possible in the future\n"
424 " we can do some enhancements like \"list all of the tests in a given\n"
425 " directory\".\n"
426 "\n"
427 " See \"gn help executable\" for usage.\n";
429 Value RunTest(Scope* scope,
430 const FunctionCallNode* function,
431 const std::vector<Value>& args,
432 BlockNode* block,
433 Err* err) {
434 return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
435 block, err);
438 } // namespace functions