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