| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "tools/gn/functions.h" | 5 #include "tools/gn/functions.h" |
| 6 | 6 |
| 7 #include "tools/gn/config_values_generator.h" | 7 #include "tools/gn/config_values_generator.h" |
| 8 #include "tools/gn/err.h" | 8 #include "tools/gn/err.h" |
| 9 #include "tools/gn/parse_tree.h" | 9 #include "tools/gn/parse_tree.h" |
| 10 #include "tools/gn/scope.h" | 10 #include "tools/gn/scope.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 " completed before any part of the action is run so it can depend on\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" \ | 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" \ | 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"\ | 84 " action are started. This can give additional parallelism in the build\n"\ |
| 85 " for runtime-only dependencies.\n" | 85 " for runtime-only dependencies.\n" |
| 86 | 86 |
| 87 const char kAction[] = "action"; | 87 const char kAction[] = "action"; |
| 88 const char kAction_HelpShort[] = | 88 const char kAction_HelpShort[] = |
| 89 "action: Declare a target that runs a script a single time."; | 89 "action: Declare a target that runs a script a single time."; |
| 90 const char kAction_Help[] = | 90 const char kAction_Help[] = |
| 91 "action: Declare a target that runs a script a single time.\n" | 91 R"(action: Declare a target that runs a script a single time. |
| 92 "\n" | 92 |
| 93 " This target type allows you to run a script a single time to produce\n" | 93 This target type allows you to run a script a single time to produce one or |
| 94 " one or more output files. If you want to run a script once for each of\n" | 94 more output files. If you want to run a script once for each of a set of |
| 95 " a set of input files, see \"gn help action_foreach\".\n" | 95 input files, see "gn help action_foreach". |
| 96 "\n" | 96 |
| 97 "Inputs\n" | 97 Inputs |
| 98 "\n" | 98 |
| 99 " In an action the \"sources\" and \"inputs\" are treated the same:\n" | 99 In an action the "sources" and "inputs" are treated the same: they're both |
| 100 " they're both input dependencies on script execution with no special\n" | 100 input dependencies on script execution with no special handling. If you want |
| 101 " handling. If you want to pass the sources to your script, you must do\n" | 101 to pass the sources to your script, you must do so explicitly by including |
| 102 " so explicitly by including them in the \"args\". Note also that this\n" | 102 them in the "args". Note also that this means there is no special handling of |
| 103 " means there is no special handling of paths since GN doesn't know\n" | 103 paths since GN doesn't know which of the args are paths and not. You will |
| 104 " which of the args are paths and not. You will want to use\n" | 104 want to use rebase_path() to convert paths to be relative to the |
| 105 " rebase_path() to convert paths to be relative to the root_build_dir.\n" | 105 root_build_dir. |
| 106 "\n" | 106 |
| 107 " You can dynamically write input dependencies (for incremental rebuilds\n" | 107 You can dynamically write input dependencies (for incremental rebuilds if an |
| 108 " if an input file changes) by writing a depfile when the script is run\n" | 108 input file changes) by writing a depfile when the script is run (see "gn help |
| 109 " (see \"gn help depfile\"). This is more flexible than \"inputs\".\n" | 109 depfile"). This is more flexible than "inputs". |
| 110 "\n" | 110 |
| 111 " If the command line length is very long, you can use response files\n" | 111 If the command line length is very long, you can use response files to pass |
| 112 " to pass args to your script. See \"gn help response_file_contents\".\n" | 112 args to your script. See "gn help response_file_contents". |
| 113 "\n" | 113 |
| 114 " It is recommended you put inputs to your script in the \"sources\"\n" | 114 It is recommended you put inputs to your script in the "sources" variable, |
| 115 " variable, and stuff like other Python files required to run your\n" | 115 and stuff like other Python files required to run your script in the "inputs" |
| 116 " script in the \"inputs\" variable.\n" | 116 variable. |
| 117 "\n" | 117 )" |
| 118 ACTION_DEPS | 118 |
| 119 "\n" | 119 ACTION_DEPS |
| 120 "Outputs\n" | 120 |
| 121 "\n" | 121 R"( |
| 122 " You should specify files created by your script by specifying them in\n" | 122 Outputs |
| 123 " the \"outputs\".\n" | 123 |
| 124 "\n" | 124 You should specify files created by your script by specifying them in the |
| 125 SCRIPT_EXECUTION_CONTEXT | 125 "outputs". |
| 126 "\n" | 126 )" |
| 127 "File name handling\n" | 127 |
| 128 "\n" | 128 SCRIPT_EXECUTION_CONTEXT |
| 129 SCRIPT_EXECUTION_OUTPUTS | 129 |
| 130 "\n" | 130 R"( |
| 131 "Variables\n" | 131 File name handling |
| 132 "\n" | 132 )" |
| 133 " args, console, data, data_deps, depfile, deps, inputs, outputs*,\n" | 133 |
| 134 " response_file_contents, script*, sources\n" | 134 SCRIPT_EXECUTION_OUTPUTS |
| 135 " * = required\n" | 135 |
| 136 "\n" | 136 R"( |
| 137 "Example\n" | 137 Variables |
| 138 "\n" | 138 |
| 139 " action(\"run_this_guy_once\") {\n" | 139 args, console, data, data_deps, depfile, deps, inputs, outputs*, |
| 140 " script = \"doprocessing.py\"\n" | 140 response_file_contents, script*, sources |
| 141 " sources = [ \"my_configuration.txt\" ]\n" | 141 * = required |
| 142 " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n" | 142 |
| 143 "\n" | 143 Example |
| 144 " # Our script imports this Python file so we want to rebuild if it\n" | 144 |
| 145 " # changes.\n" | 145 action("run_this_guy_once") { |
| 146 " inputs = [ \"helper_library.py\" ]\n" | 146 script = "doprocessing.py" |
| 147 "\n" | 147 sources = [ "my_configuration.txt" ] |
| 148 " # Note that we have to manually pass the sources to our script if\n" | 148 outputs = [ "$target_gen_dir/insightful_output.txt" ] |
| 149 " # the script needs them as inputs.\n" | 149 |
| 150 " args = [ \"--out\", rebase_path(target_gen_dir, root_build_dir) ] +\n" | 150 # Our script imports this Python file so we want to rebuild if it changes. |
| 151 " rebase_path(sources, root_build_dir)\n" | 151 inputs = [ "helper_library.py" ] |
| 152 " }\n"; | 152 |
| 153 # Note that we have to manually pass the sources to our script if the |
| 154 # script needs them as inputs. |
| 155 args = [ "--out", rebase_path(target_gen_dir, root_build_dir) ] + |
| 156 rebase_path(sources, root_build_dir) |
| 157 })"; |
| 153 | 158 |
| 154 Value RunAction(Scope* scope, | 159 Value RunAction(Scope* scope, |
| 155 const FunctionCallNode* function, | 160 const FunctionCallNode* function, |
| 156 const std::vector<Value>& args, | 161 const std::vector<Value>& args, |
| 157 BlockNode* block, | 162 BlockNode* block, |
| 158 Err* err) { | 163 Err* err) { |
| 159 return ExecuteGenericTarget(functions::kAction, scope, function, args, | 164 return ExecuteGenericTarget(functions::kAction, scope, function, args, |
| 160 block, err); | 165 block, err); |
| 161 } | 166 } |
| 162 | 167 |
| 163 // action_foreach -------------------------------------------------------------- | 168 // action_foreach -------------------------------------------------------------- |
| 164 | 169 |
| 165 const char kActionForEach[] = "action_foreach"; | 170 const char kActionForEach[] = "action_foreach"; |
| 166 const char kActionForEach_HelpShort[] = | 171 const char kActionForEach_HelpShort[] = |
| 167 "action_foreach: Declare a target that runs a script over a set of files."; | 172 "action_foreach: Declare a target that runs a script over a set of files."; |
| 168 const char kActionForEach_Help[] = | 173 const char kActionForEach_Help[] = |
| 169 "action_foreach: Declare a target that runs a script over a set of files.\n" | 174 R"(action_foreach: Declare a target that runs a script over a set of files. |
| 170 "\n" | 175 |
| 171 " This target type allows you to run a script once-per-file over a set\n" | 176 This target type allows you to run a script once-per-file over a set of |
| 172 " of sources. If you want to run a script once that takes many files as\n" | 177 sources. If you want to run a script once that takes many files as input, see |
| 173 " input, see \"gn help action\".\n" | 178 "gn help action". |
| 174 "\n" | 179 |
| 175 "Inputs\n" | 180 Inputs |
| 176 "\n" | 181 |
| 177 " The script will be run once per file in the \"sources\" variable. The\n" | 182 The script will be run once per file in the "sources" variable. The "outputs" |
| 178 " \"outputs\" variable should specify one or more files with a source\n" | 183 variable should specify one or more files with a source expansion pattern in |
| 179 " expansion pattern in it (see \"gn help source_expansion\"). The output\n" | 184 it (see "gn help source_expansion"). The output file(s) for each script |
| 180 " file(s) for each script invocation should be unique. Normally you\n" | 185 invocation should be unique. Normally you use "{{source_name_part}}" in each |
| 181 " use \"{{source_name_part}}\" in each output file.\n" | 186 output file. |
| 182 "\n" | 187 |
| 183 " If your script takes additional data as input, such as a shared\n" | 188 If your script takes additional data as input, such as a shared configuration |
| 184 " configuration file or a Python module it uses, those files should be\n" | 189 file or a Python module it uses, those files should be listed in the "inputs" |
| 185 " listed in the \"inputs\" variable. These files are treated as\n" | 190 variable. These files are treated as dependencies of each script invocation. |
| 186 " dependencies of each script invocation.\n" | 191 |
| 187 "\n" | 192 If the command line length is very long, you can use response files to pass |
| 188 " If the command line length is very long, you can use response files\n" | 193 args to your script. See "gn help response_file_contents". |
| 189 " to pass args to your script. See \"gn help response_file_contents\".\n" | 194 |
| 190 "\n" | 195 You can dynamically write input dependencies (for incremental rebuilds if an |
| 191 " You can dynamically write input dependencies (for incremental rebuilds\n" | 196 input file changes) by writing a depfile when the script is run (see "gn help |
| 192 " if an input file changes) by writing a depfile when the script is run\n" | 197 depfile"). This is more flexible than "inputs". |
| 193 " (see \"gn help depfile\"). This is more flexible than \"inputs\".\n" | 198 )" |
| 194 "\n" | 199 ACTION_DEPS |
| 195 ACTION_DEPS | 200 R"( |
| 196 "\n" | 201 Outputs |
| 197 "Outputs\n" | 202 )" |
| 198 "\n" | 203 SCRIPT_EXECUTION_CONTEXT |
| 199 SCRIPT_EXECUTION_CONTEXT | 204 R"( |
| 200 "\n" | 205 File name handling |
| 201 "File name handling\n" | 206 )" |
| 202 "\n" | 207 SCRIPT_EXECUTION_OUTPUTS |
| 203 SCRIPT_EXECUTION_OUTPUTS | 208 R"( |
| 204 "\n" | 209 Variables |
| 205 "Variables\n" | 210 |
| 206 "\n" | 211 args, console, data, data_deps, depfile, deps, inputs, outputs*, |
| 207 " args, console, data, data_deps, depfile, deps, inputs, outputs*,\n" | 212 response_file_contents, script*, sources* |
| 208 " response_file_contents, script*, sources*\n" | 213 * = required |
| 209 " * = required\n" | 214 |
| 210 "\n" | 215 Example |
| 211 "Example\n" | 216 |
| 212 "\n" | 217 # Runs the script over each IDL file. The IDL script will generate both a .cc |
| 213 " # Runs the script over each IDL file. The IDL script will generate\n" | 218 # and a .h file for each input. |
| 214 " # both a .cc and a .h file for each input.\n" | 219 action_foreach("my_idl") { |
| 215 " action_foreach(\"my_idl\") {\n" | 220 script = "idl_processor.py" |
| 216 " script = \"idl_processor.py\"\n" | 221 sources = [ "foo.idl", "bar.idl" ] |
| 217 " sources = [ \"foo.idl\", \"bar.idl\" ]\n" | 222 |
| 218 "\n" | 223 # Our script reads this file each time, so we need to list is as a |
| 219 " # Our script reads this file each time, so we need to list is as a\n" | 224 # dependency so we can rebuild if it changes. |
| 220 " # dependency so we can rebuild if it changes.\n" | 225 inputs = [ "my_configuration.txt" ] |
| 221 " inputs = [ \"my_configuration.txt\" ]\n" | 226 |
| 222 "\n" | 227 # Transformation from source file name to output file names. |
| 223 " # Transformation from source file name to output file names.\n" | 228 outputs = [ "$target_gen_dir/{{source_name_part}}.h", |
| 224 " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\",\n" | 229 "$target_gen_dir/{{source_name_part}}.cc" ] |
| 225 " \"$target_gen_dir/{{source_name_part}}.cc\" ]\n" | 230 |
| 226 "\n" | 231 # Note that since "args" is opaque to GN, if you specify paths here, you |
| 227 " # Note that since \"args\" is opaque to GN, if you specify paths\n" | 232 # will need to convert it to be relative to the build directory using |
| 228 " # here, you will need to convert it to be relative to the build\n" | 233 # rebase_path(). |
| 229 " # directory using \"rebase_path()\".\n" | 234 args = [ |
| 230 " args = [\n" | 235 "{{source}}", |
| 231 " \"{{source}}\",\n" | 236 "-o", |
| 232 " \"-o\",\n" | 237 rebase_path(relative_target_gen_dir, root_build_dir) + |
| 233 " rebase_path(relative_target_gen_dir, root_build_dir) +\n" | 238 "/{{source_name_part}}.h" ] |
| 234 " \"/{{source_name_part}}.h\" ]\n" | 239 })"; |
| 235 " }\n" | 240 |
| 236 "\n"; | |
| 237 Value RunActionForEach(Scope* scope, | 241 Value RunActionForEach(Scope* scope, |
| 238 const FunctionCallNode* function, | 242 const FunctionCallNode* function, |
| 239 const std::vector<Value>& args, | 243 const std::vector<Value>& args, |
| 240 BlockNode* block, | 244 BlockNode* block, |
| 241 Err* err) { | 245 Err* err) { |
| 242 return ExecuteGenericTarget(functions::kActionForEach, scope, function, args, | 246 return ExecuteGenericTarget(functions::kActionForEach, scope, function, args, |
| 243 block, err); | 247 block, err); |
| 244 } | 248 } |
| 245 | 249 |
| 246 // bundle_data ----------------------------------------------------------------- | 250 // bundle_data ----------------------------------------------------------------- |
| 247 | 251 |
| 248 const char kBundleData[] = "bundle_data"; | 252 const char kBundleData[] = "bundle_data"; |
| 249 const char kBundleData_HelpShort[] = | 253 const char kBundleData_HelpShort[] = |
| 250 "bundle_data: [iOS/OS X] Declare a target without output."; | 254 "bundle_data: [iOS/OS X] Declare a target without output."; |
| 251 const char kBundleData_Help[] = | 255 const char kBundleData_Help[] = |
| 252 "bundle_data: [iOS/OS X] Declare a target without output.\n" | 256 R"(bundle_data: [iOS/OS X] Declare a target without output. |
| 253 "\n" | 257 |
| 254 " This target type allows to declare data that is required at runtime.\n" | 258 This target type allows to declare data that is required at runtime. It is |
| 255 " It is used to inform \"create_bundle\" targets of the files to copy\n" | 259 used to inform "create_bundle" targets of the files to copy into generated |
| 256 " into generated bundle, see \"gn help create_bundle\" for help.\n" | 260 bundle, see "gn help create_bundle" for help. |
| 257 "\n" | 261 |
| 258 " The target must define a list of files as \"sources\" and a single\n" | 262 The target must define a list of files as "sources" and a single "outputs". |
| 259 " \"outputs\". If there are multiple files, source expansions must be\n" | 263 If there are multiple files, source expansions must be used to express the |
| 260 " used to express the output. The output must reference a file inside\n" | 264 output. The output must reference a file inside of {{bundle_root_dir}}. |
| 261 " of {{bundle_root_dir}}.\n" | 265 |
| 262 "\n" | 266 This target can be used on all platforms though it is designed only to |
| 263 " This target can be used on all platforms though it is designed only to\n" | 267 generate iOS/OS X bundle. In cross-platform projects, it is advised to put it |
| 264 " generate iOS/OS X bundle. In cross-platform projects, it is advised to\n" | 268 behind iOS/Mac conditionals. |
| 265 " put it behind iOS/Mac conditionals.\n" | 269 |
| 266 "\n" | 270 See "gn help create_bundle" for more information. |
| 267 " See \"gn help create_bundle\" for more information.\n" | 271 |
| 268 "\n" | 272 Variables |
| 269 "Variables\n" | 273 |
| 270 "\n" | 274 sources*, outputs*, deps, data_deps, public_deps, visibility |
| 271 " sources*, outputs*, deps, data_deps, public_deps, visibility\n" | 275 * = required |
| 272 " * = required\n" | 276 |
| 273 "\n" | 277 Examples |
| 274 "Examples\n" | 278 |
| 275 "\n" | 279 bundle_data("icudata") { |
| 276 " bundle_data(\"icudata\") {\n" | 280 sources = [ "sources/data/in/icudtl.dat" ] |
| 277 " sources = [ \"sources/data/in/icudtl.dat\" ]\n" | 281 outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ] |
| 278 " outputs = [ \"{{bundle_resources_dir}}/{{source_file_part}}\" ]\n" | 282 } |
| 279 " }\n" | 283 |
| 280 "\n" | 284 bundle_data("base_unittests_bundle_data]") { |
| 281 " bundle_data(\"base_unittests_bundle_data]\") {\n" | 285 sources = [ "test/data" ] |
| 282 " sources = [ \"test/data\" ]\n" | 286 outputs = [ |
| 283 " outputs = [\n" | 287 "{{bundle_resources_dir}}/{{source_root_relative_dir}}/" + |
| 284 " \"{{bundle_resources_dir}}/{{source_root_relative_dir}}/\" +\n" | 288 "{{source_file_part}}" |
| 285 " \"{{source_file_part}}\"\n" | 289 ] |
| 286 " ]\n" | 290 } |
| 287 " }\n" | 291 |
| 288 "\n" | 292 bundle_data("material_typography_bundle_data") { |
| 289 " bundle_data(\"material_typography_bundle_data\") {\n" | 293 sources = [ |
| 290 " sources = [\n" | 294 "src/MaterialTypography.bundle/Roboto-Bold.ttf", |
| 291 " \"src/MaterialTypography.bundle/Roboto-Bold.ttf\",\n" | 295 "src/MaterialTypography.bundle/Roboto-Italic.ttf", |
| 292 " \"src/MaterialTypography.bundle/Roboto-Italic.ttf\",\n" | 296 "src/MaterialTypography.bundle/Roboto-Regular.ttf", |
| 293 " \"src/MaterialTypography.bundle/Roboto-Regular.ttf\",\n" | 297 "src/MaterialTypography.bundle/Roboto-Thin.ttf", |
| 294 " \"src/MaterialTypography.bundle/Roboto-Thin.ttf\",\n" | 298 ] |
| 295 " ]\n" | 299 outputs = [ |
| 296 " outputs = [\n" | 300 "{{bundle_resources_dir}}/MaterialTypography.bundle/" |
| 297 " \"{{bundle_resources_dir}}/MaterialTypography.bundle/\"\n" | 301 "{{source_file_part}}" |
| 298 " \"{{source_file_part}}\"\n" | 302 ] |
| 299 " ]\n" | 303 })"; |
| 300 " }\n"; | |
| 301 | 304 |
| 302 Value RunBundleData(Scope* scope, | 305 Value RunBundleData(Scope* scope, |
| 303 const FunctionCallNode* function, | 306 const FunctionCallNode* function, |
| 304 const std::vector<Value>& args, | 307 const std::vector<Value>& args, |
| 305 BlockNode* block, | 308 BlockNode* block, |
| 306 Err* err) { | 309 Err* err) { |
| 307 return ExecuteGenericTarget(functions::kBundleData, scope, function, args, | 310 return ExecuteGenericTarget(functions::kBundleData, scope, function, args, |
| 308 block, err); | 311 block, err); |
| 309 } | 312 } |
| 310 | 313 |
| 311 // create_bundle --------------------------------------------------------------- | 314 // create_bundle --------------------------------------------------------------- |
| 312 | 315 |
| 313 const char kCreateBundle[] = "create_bundle"; | 316 const char kCreateBundle[] = "create_bundle"; |
| 314 const char kCreateBundle_HelpShort[] = | 317 const char kCreateBundle_HelpShort[] = |
| 315 "create_bundle: [iOS/OS X] Build an OS X / iOS bundle."; | 318 "create_bundle: [iOS/OS X] Build an OS X / iOS bundle."; |
| 316 const char kCreateBundle_Help[] = | 319 const char kCreateBundle_Help[] = |
| 317 "create_bundle: [iOS/OS X] Build an OS X / iOS bundle.\n" | 320 R"(create_bundle: [iOS/OS X] Build an OS X / iOS bundle. |
| 318 "\n" | 321 |
| 319 " This target generates an iOS/OS X bundle (which is a directory with a\n" | 322 This target generates an iOS/OS X bundle (which is a directory with a |
| 320 " well-know structure). This target does not define any sources, instead\n" | 323 well-know structure). This target does not define any sources, instead they |
| 321 " they are computed from all \"bundle_data\" target this one depends on\n" | 324 are computed from all "bundle_data" target this one depends on transitively |
| 322 " transitively (the recursion stops at \"create_bundle\" targets).\n" | 325 (the recursion stops at "create_bundle" targets). |
| 323 "\n" | 326 |
| 324 " The \"bundle_*_dir\" properties must be defined. They will be used for\n" | 327 The "bundle_*_dir" properties must be defined. They will be used for the |
| 325 " the expansion of {{bundle_*_dir}} rules in \"bundle_data\" outputs.\n" | 328 expansion of {{bundle_*_dir}} rules in "bundle_data" outputs. |
| 326 "\n" | 329 |
| 327 " This target can be used on all platforms though it is designed only to\n" | 330 This target can be used on all platforms though it is designed only to |
| 328 " generate iOS/OS X bundle. In cross-platform projects, it is advised to\n" | 331 generate iOS/OS X bundle. In cross-platform projects, it is advised to put it |
| 329 " put it behind iOS/Mac conditionals.\n" | 332 behind iOS/Mac conditionals. |
| 330 "\n" | 333 |
| 331 " If a create_bundle is specified as a data_deps for another target, the\n" | 334 If a create_bundle is specified as a data_deps for another target, the bundle |
| 332 " bundle is considered a leaf, and its public and private dependencies\n" | 335 is considered a leaf, and its public and private dependencies will not |
| 333 " will not contribute to any data or data_deps. Required runtime\n" | 336 contribute to any data or data_deps. Required runtime dependencies should be |
| 334 " dependencies should be placed in the bundle. A create_bundle can\n" | 337 placed in the bundle. A create_bundle can declare its own explicit data and |
| 335 " declare its own explicit data and data_deps, however.\n" | 338 data_deps, however. |
| 336 "\n" | 339 |
| 337 "Code signing\n" | 340 Code signing |
| 338 "\n" | 341 |
| 339 " Some bundle needs to be code signed as part of the build (on iOS all\n" | 342 Some bundle needs to be code signed as part of the build (on iOS all |
| 340 " application needs to be code signed to run on a device). The code\n" | 343 application needs to be code signed to run on a device). The code signature |
| 341 " signature can be configured via the code_signing_script variable.\n" | 344 can be configured via the code_signing_script variable. |
| 342 "\n" | 345 |
| 343 " If set, code_signing_script is the path of a script that invoked after\n" | 346 If set, code_signing_script is the path of a script that invoked after all |
| 344 " all files have been moved into the bundle. The script must not change\n" | 347 files have been moved into the bundle. The script must not change any file in |
| 345 " any file in the bundle, but may add new files.\n" | 348 the bundle, but may add new files. |
| 346 "\n" | 349 |
| 347 " If code_signing_script is defined, then code_signing_outputs must also\n" | 350 If code_signing_script is defined, then code_signing_outputs must also be |
| 348 " be defined and non-empty to inform when the script needs to be re-run.\n" | 351 defined and non-empty to inform when the script needs to be re-run. The |
| 349 " The code_signing_args will be passed as is to the script (so path have\n" | 352 code_signing_args will be passed as is to the script (so path have to be |
| 350 " to be rebased) and additional inputs may be listed with the variable\n" | 353 rebased) and additional inputs may be listed with the variable |
| 351 " code_signing_sources.\n" | 354 code_signing_sources. |
| 352 "\n" | 355 |
| 353 "Variables\n" | 356 Variables |
| 354 "\n" | 357 |
| 355 " bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,\n" | 358 bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*, |
| 356 " bundle_plugins_dir*, bundle_deps_filter, deps, data_deps, public_deps,\n" | 359 bundle_plugins_dir*, bundle_deps_filter, deps, data_deps, public_deps, |
| 357 " visibility, product_type, code_signing_args, code_signing_script,\n" | 360 visibility, product_type, code_signing_args, code_signing_script, |
| 358 " code_signing_sources, code_signing_outputs\n" | 361 code_signing_sources, code_signing_outputs |
| 359 " * = required\n" | 362 * = required |
| 360 "\n" | 363 |
| 361 "Example\n" | 364 Example |
| 362 "\n" | 365 |
| 363 " # Defines a template to create an application. On most platform, this\n" | 366 # Defines a template to create an application. On most platform, this is just |
| 364 " # is just an alias for an \"executable\" target, but on iOS/OS X, it\n" | 367 # an alias for an "executable" target, but on iOS/OS X, it builds an |
| 365 " # builds an application bundle.\n" | 368 # application bundle. |
| 366 " template(\"app\") {\n" | 369 template("app") { |
| 367 " if (!is_ios && !is_mac) {\n" | 370 if (!is_ios && !is_mac) { |
| 368 " executable(target_name) {\n" | 371 executable(target_name) { |
| 369 " forward_variables_from(invoker, \"*\")\n" | 372 forward_variables_from(invoker, "*") |
| 370 " }\n" | 373 } |
| 371 " } else {\n" | 374 } else { |
| 372 " app_name = target_name\n" | 375 app_name = target_name |
| 373 " gen_path = target_gen_dir\n" | 376 gen_path = target_gen_dir |
| 374 "\n" | 377 |
| 375 " action(\"${app_name}_generate_info_plist\") {\n" | 378 action("${app_name}_generate_info_plist") { |
| 376 " script = [ \"//build/ios/ios_gen_plist.py\" ]\n" | 379 script = [ "//build/ios/ios_gen_plist.py" ] |
| 377 " sources = [ \"templates/Info.plist\" ]\n" | 380 sources = [ "templates/Info.plist" ] |
| 378 " outputs = [ \"$gen_path/Info.plist\" ]\n" | 381 outputs = [ "$gen_path/Info.plist" ] |
| 379 " args = rebase_path(sources, root_build_dir) +\n" | 382 args = rebase_path(sources, root_build_dir) + |
| 380 " rebase_path(outputs, root_build_dir)\n" | 383 rebase_path(outputs, root_build_dir) |
| 381 " }\n" | 384 } |
| 382 "\n" | 385 |
| 383 " bundle_data(\"${app_name}_bundle_info_plist\") {\n" | 386 bundle_data("${app_name}_bundle_info_plist") { |
| 384 " deps = [ \":${app_name}_generate_info_plist\" ]\n" | 387 deps = [ ":${app_name}_generate_info_plist" ] |
| 385 " sources = [ \"$gen_path/Info.plist\" ]\n" | 388 sources = [ "$gen_path/Info.plist" ] |
| 386 " outputs = [ \"{{bundle_root_dir}}/Info.plist\" ]\n" | 389 outputs = [ "{{bundle_root_dir}}/Info.plist" ] |
| 387 " }\n" | 390 } |
| 388 "\n" | 391 |
| 389 " executable(\"${app_name}_generate_executable\") {\n" | 392 executable("${app_name}_generate_executable") { |
| 390 " forward_variables_from(invoker, \"*\", [\n" | 393 forward_variables_from(invoker, "*", [ |
| 391 " \"output_name\",\n" | 394 "output_name", |
| 392 " \"visibility\",\n" | 395 "visibility", |
| 393 " ])\n" | 396 ]) |
| 394 " output_name =\n" | 397 output_name = |
| 395 " rebase_path(\"$gen_path/$app_name\", root_build_dir)\n" | 398 rebase_path("$gen_path/$app_name", root_build_dir) |
| 396 " }\n" | 399 } |
| 397 "\n" | 400 |
| 398 " code_signing =\n" | 401 code_signing = |
| 399 " defined(invoker.code_signing) && invoker.code_signing\n" | 402 defined(invoker.code_signing) && invoker.code_signing |
| 400 "\n" | 403 |
| 401 " if (is_ios && !code_signing) {\n" | 404 if (is_ios && !code_signing) { |
| 402 " bundle_data(\"${app_name}_bundle_executable\") {\n" | 405 bundle_data("${app_name}_bundle_executable") { |
| 403 " deps = [ \":${app_name}_generate_executable\" ]\n" | 406 deps = [ ":${app_name}_generate_executable" ] |
| 404 " sources = [ \"$gen_path/$app_name\" ]\n" | 407 sources = [ "$gen_path/$app_name" ] |
| 405 " outputs = [ \"{{bundle_executable_dir}}/$app_name\" ]\n" | 408 outputs = [ "{{bundle_executable_dir}}/$app_name" ] |
| 406 " }\n" | 409 } |
| 407 " }\n" | 410 } |
| 408 "\n" | 411 |
| 409 " create_bundle(\"${app_name}.app\") {\n" | 412 create_bundle("${app_name}.app") { |
| 410 " product_type = \"com.apple.product-type.application\"\n" | 413 product_type = "com.apple.product-type.application" |
| 411 " if (is_ios) {\n" | 414 if (is_ios) { |
| 412 " bundle_root_dir = \"${root_build_dir}/$target_name\"\n" | 415 bundle_root_dir = "${root_build_dir}/$target_name" |
| 413 " bundle_resources_dir = bundle_root_dir\n" | 416 bundle_resources_dir = bundle_root_dir |
| 414 " bundle_executable_dir = bundle_root_dir\n" | 417 bundle_executable_dir = bundle_root_dir |
| 415 " bundle_plugins_dir = bundle_root_dir + \"/Plugins\"\n" | 418 bundle_plugins_dir = bundle_root_dir + "/Plugins" |
| 416 " } else {\n" | 419 } else { |
| 417 " bundle_root_dir = \"${root_build_dir}/target_name/Contents\"\n" | 420 bundle_root_dir = "${root_build_dir}/target_name/Contents" |
| 418 " bundle_resources_dir = bundle_root_dir + \"/Resources\"\n" | 421 bundle_resources_dir = bundle_root_dir + "/Resources" |
| 419 " bundle_executable_dir = bundle_root_dir + \"/MacOS\"\n" | 422 bundle_executable_dir = bundle_root_dir + "/MacOS" |
| 420 " bundle_plugins_dir = bundle_root_dir + \"/Plugins\"\n" | 423 bundle_plugins_dir = bundle_root_dir + "/Plugins" |
| 421 " }\n" | 424 } |
| 422 " deps = [ \":${app_name}_bundle_info_plist\" ]\n" | 425 deps = [ ":${app_name}_bundle_info_plist" ] |
| 423 " if (is_ios && code_signing) {\n" | 426 if (is_ios && code_signing) { |
| 424 " deps += [ \":${app_name}_generate_executable\" ]\n" | 427 deps += [ ":${app_name}_generate_executable" ] |
| 425 " code_signing_script = \"//build/config/ios/codesign.py\"\n" | 428 code_signing_script = "//build/config/ios/codesign.py" |
| 426 " code_signing_sources = [\n" | 429 code_signing_sources = [ |
| 427 " invoker.entitlements_path,\n" | 430 invoker.entitlements_path, |
| 428 " \"$target_gen_dir/$app_name\",\n" | 431 "$target_gen_dir/$app_name", |
| 429 " ]\n" | 432 ] |
| 430 " code_signing_outputs = [\n" | 433 code_signing_outputs = [ |
| 431 " \"$bundle_root_dir/$app_name\",\n" | 434 "$bundle_root_dir/$app_name", |
| 432 " \"$bundle_root_dir/_CodeSignature/CodeResources\",\n" | 435 "$bundle_root_dir/_CodeSignature/CodeResources", |
| 433 " \"$bundle_root_dir/embedded.mobileprovision\",\n" | 436 "$bundle_root_dir/embedded.mobileprovision", |
| 434 " \"$target_gen_dir/$app_name.xcent\",\n" | 437 "$target_gen_dir/$app_name.xcent", |
| 435 " ]\n" | 438 ] |
| 436 " code_signing_args = [\n" | 439 code_signing_args = [ |
| 437 " \"-i=\" + ios_code_signing_identity,\n" | 440 "-i=" + ios_code_signing_identity, |
| 438 " \"-b=\" + rebase_path(\n" | 441 "-b=" + rebase_path( |
| 439 " \"$target_gen_dir/$app_name\", root_build_dir),\n" | 442 "$target_gen_dir/$app_name", root_build_dir), |
| 440 " \"-e=\" + rebase_path(\n" | 443 "-e=" + rebase_path( |
| 441 " invoker.entitlements_path, root_build_dir),\n" | 444 invoker.entitlements_path, root_build_dir), |
| 442 " \"-e=\" + rebase_path(\n" | 445 "-e=" + rebase_path( |
| 443 " \"$target_gen_dir/$app_name.xcent\", root_build_dir),\n" | 446 "$target_gen_dir/$app_name.xcent", root_build_dir), |
| 444 " rebase_path(bundle_root_dir, root_build_dir),\n" | 447 rebase_path(bundle_root_dir, root_build_dir), |
| 445 " ]\n" | 448 ] |
| 446 " } else {\n" | 449 } else { |
| 447 " deps += [ \":${app_name}_bundle_executable\" ]\n" | 450 deps += [ ":${app_name}_bundle_executable" ] |
| 448 " }\n" | 451 } |
| 449 " }\n" | 452 } |
| 450 " }\n" | 453 } |
| 451 " }\n"; | 454 })"; |
| 452 | 455 |
| 453 Value RunCreateBundle(Scope* scope, | 456 Value RunCreateBundle(Scope* scope, |
| 454 const FunctionCallNode* function, | 457 const FunctionCallNode* function, |
| 455 const std::vector<Value>& args, | 458 const std::vector<Value>& args, |
| 456 BlockNode* block, | 459 BlockNode* block, |
| 457 Err* err) { | 460 Err* err) { |
| 458 return ExecuteGenericTarget(functions::kCreateBundle, scope, function, args, | 461 return ExecuteGenericTarget(functions::kCreateBundle, scope, function, args, |
| 459 block, err); | 462 block, err); |
| 460 } | 463 } |
| 461 | 464 |
| 462 // copy ------------------------------------------------------------------------ | 465 // copy ------------------------------------------------------------------------ |
| 463 | 466 |
| 464 const char kCopy[] = "copy"; | 467 const char kCopy[] = "copy"; |
| 465 const char kCopy_HelpShort[] = | 468 const char kCopy_HelpShort[] = |
| 466 "copy: Declare a target that copies files."; | 469 "copy: Declare a target that copies files."; |
| 467 const char kCopy_Help[] = | 470 const char kCopy_Help[] = |
| 468 "copy: Declare a target that copies files.\n" | 471 R"(copy: Declare a target that copies files. |
| 469 "\n" | 472 |
| 470 "File name handling\n" | 473 File name handling |
| 471 "\n" | 474 |
| 472 " All output files must be inside the output directory of the build.\n" | 475 All output files must be inside the output directory of the build. You would |
| 473 " You would generally use |$target_out_dir| or |$target_gen_dir| to\n" | 476 generally use |$target_out_dir| or |$target_gen_dir| to reference the output |
| 474 " reference the output or generated intermediate file directories,\n" | 477 or generated intermediate file directories, respectively. |
| 475 " respectively.\n" | 478 |
| 476 "\n" | 479 Both "sources" and "outputs" must be specified. Sources can include as many |
| 477 " Both \"sources\" and \"outputs\" must be specified. Sources can " | 480 files as you want, but there can only be one item in the outputs list (plural |
| 478 "include\n" | 481 is used for the name for consistency with other target types). |
| 479 " as many files as you want, but there can only be one item in the\n" | 482 |
| 480 " outputs list (plural is used for the name for consistency with\n" | 483 If there is more than one source file, your output name should specify a |
| 481 " other target types).\n" | 484 mapping from each source file to an output file name using source expansion |
| 482 "\n" | 485 (see "gn help source_expansion"). The placeholders will look like |
| 483 " If there is more than one source file, your output name should specify\n" | 486 "{{source_name_part}}", for example. |
| 484 " a mapping from each source file to an output file name using source\n" | 487 |
| 485 " expansion (see \"gn help source_expansion\"). The placeholders will\n" | 488 Examples |
| 486 " look like \"{{source_name_part}}\", for example.\n" | 489 |
| 487 "\n" | 490 # Write a rule that copies a checked-in DLL to the output directory. |
| 488 "Examples\n" | 491 copy("mydll") { |
| 489 "\n" | 492 sources = [ "mydll.dll" ] |
| 490 " # Write a rule that copies a checked-in DLL to the output directory.\n" | 493 outputs = [ "$target_out_dir/mydll.dll" ] |
| 491 " copy(\"mydll\") {\n" | 494 } |
| 492 " sources = [ \"mydll.dll\" ]\n" | 495 |
| 493 " outputs = [ \"$target_out_dir/mydll.dll\" ]\n" | 496 # Write a rule to copy several files to the target generated files directory. |
| 494 " }\n" | 497 copy("myfiles") { |
| 495 "\n" | 498 sources = [ "data1.dat", "data2.dat", "data3.dat" ] |
| 496 " # Write a rule to copy several files to the target generated files\n" | 499 |
| 497 " # directory.\n" | 500 # Use source expansion to generate output files with the corresponding file |
| 498 " copy(\"myfiles\") {\n" | 501 # names in the gen dir. This will just copy each file. |
| 499 " sources = [ \"data1.dat\", \"data2.dat\", \"data3.dat\" ]\n" | 502 outputs = [ "$target_gen_dir/{{source_file_part}}" ] |
| 500 "\n" | 503 })"; |
| 501 " # Use source expansion to generate output files with the\n" | |
| 502 " # corresponding file names in the gen dir. This will just copy each\n" | |
| 503 " # file.\n" | |
| 504 " outputs = [ \"$target_gen_dir/{{source_file_part}}\" ]\n" | |
| 505 " }\n"; | |
| 506 | 504 |
| 507 Value RunCopy(const FunctionCallNode* function, | 505 Value RunCopy(const FunctionCallNode* function, |
| 508 const std::vector<Value>& args, | 506 const std::vector<Value>& args, |
| 509 Scope* scope, | 507 Scope* scope, |
| 510 Err* err) { | 508 Err* err) { |
| 511 if (!EnsureNotProcessingImport(function, scope, err) || | 509 if (!EnsureNotProcessingImport(function, scope, err) || |
| 512 !EnsureNotProcessingBuildConfig(function, scope, err)) | 510 !EnsureNotProcessingBuildConfig(function, scope, err)) |
| 513 return Value(); | 511 return Value(); |
| 514 TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err); | 512 TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err); |
| 515 return Value(); | 513 return Value(); |
| 516 } | 514 } |
| 517 | 515 |
| 518 // executable ------------------------------------------------------------------ | 516 // executable ------------------------------------------------------------------ |
| 519 | 517 |
| 520 const char kExecutable[] = "executable"; | 518 const char kExecutable[] = "executable"; |
| 521 const char kExecutable_HelpShort[] = | 519 const char kExecutable_HelpShort[] = |
| 522 "executable: Declare an executable target."; | 520 "executable: Declare an executable target."; |
| 523 const char kExecutable_Help[] = | 521 const char kExecutable_Help[] = |
| 524 "executable: Declare an executable target.\n" | 522 R"(executable: Declare an executable target. |
| 525 "\n" | 523 |
| 526 "Variables\n" | 524 Variables |
| 527 "\n" | 525 )" |
| 528 CONFIG_VALUES_VARS_HELP | 526 CONFIG_VALUES_VARS_HELP |
| 529 DEPS_VARS | 527 DEPS_VARS |
| 530 DEPENDENT_CONFIG_VARS | 528 DEPENDENT_CONFIG_VARS |
| 531 GENERAL_TARGET_VARS; | 529 GENERAL_TARGET_VARS; |
| 532 | 530 |
| 533 Value RunExecutable(Scope* scope, | 531 Value RunExecutable(Scope* scope, |
| 534 const FunctionCallNode* function, | 532 const FunctionCallNode* function, |
| 535 const std::vector<Value>& args, | 533 const std::vector<Value>& args, |
| 536 BlockNode* block, | 534 BlockNode* block, |
| 537 Err* err) { | 535 Err* err) { |
| 538 return ExecuteGenericTarget(functions::kExecutable, scope, function, args, | 536 return ExecuteGenericTarget(functions::kExecutable, scope, function, args, |
| 539 block, err); | 537 block, err); |
| 540 } | 538 } |
| 541 | 539 |
| 542 // group ----------------------------------------------------------------------- | 540 // group ----------------------------------------------------------------------- |
| 543 | 541 |
| 544 const char kGroup[] = "group"; | 542 const char kGroup[] = "group"; |
| 545 const char kGroup_HelpShort[] = | 543 const char kGroup_HelpShort[] = |
| 546 "group: Declare a named group of targets."; | 544 "group: Declare a named group of targets."; |
| 547 const char kGroup_Help[] = | 545 const char kGroup_Help[] = |
| 548 "group: Declare a named group of targets.\n" | 546 R"(group: Declare a named group of targets. |
| 549 "\n" | 547 |
| 550 " This target type allows you to create meta-targets that just collect a\n" | 548 This target type allows you to create meta-targets that just collect a set of |
| 551 " set of dependencies into one named target. Groups can additionally\n" | 549 dependencies into one named target. Groups can additionally specify configs |
| 552 " specify configs that apply to their dependents.\n" | 550 that apply to their dependents. |
| 553 "\n" | 551 |
| 554 " Depending on a group is exactly like depending directly on that\n" | 552 Variables |
| 555 " group's deps. \n" | 553 )" |
| 556 "\n" | 554 |
| 557 "Variables\n" | |
| 558 "\n" | |
| 559 DEPS_VARS | 555 DEPS_VARS |
| 560 DEPENDENT_CONFIG_VARS | 556 DEPENDENT_CONFIG_VARS |
| 561 "\n" | 557 |
| 562 "Example\n" | 558 R"( |
| 563 "\n" | 559 Example |
| 564 " group(\"all\") {\n" | 560 |
| 565 " deps = [\n" | 561 group("all") { |
| 566 " \"//project:runner\",\n" | 562 deps = [ |
| 567 " \"//project:unit_tests\",\n" | 563 "//project:runner", |
| 568 " ]\n" | 564 "//project:unit_tests", |
| 569 " }\n"; | 565 ] |
| 566 })"; |
| 570 | 567 |
| 571 Value RunGroup(Scope* scope, | 568 Value RunGroup(Scope* scope, |
| 572 const FunctionCallNode* function, | 569 const FunctionCallNode* function, |
| 573 const std::vector<Value>& args, | 570 const std::vector<Value>& args, |
| 574 BlockNode* block, | 571 BlockNode* block, |
| 575 Err* err) { | 572 Err* err) { |
| 576 return ExecuteGenericTarget(functions::kGroup, scope, function, args, | 573 return ExecuteGenericTarget(functions::kGroup, scope, function, args, |
| 577 block, err); | 574 block, err); |
| 578 } | 575 } |
| 579 | 576 |
| 580 // loadable_module ------------------------------------------------------------- | 577 // loadable_module ------------------------------------------------------------- |
| 581 | 578 |
| 582 const char kLoadableModule[] = "loadable_module"; | 579 const char kLoadableModule[] = "loadable_module"; |
| 583 const char kLoadableModule_HelpShort[] = | 580 const char kLoadableModule_HelpShort[] = |
| 584 "loadable_module: Declare a loadable module target."; | 581 "loadable_module: Declare a loadable module target."; |
| 585 const char kLoadableModule_Help[] = | 582 const char kLoadableModule_Help[] = |
| 586 "loadable_module: Declare a loadable module target.\n" | 583 R"(loadable_module: Declare a loadable module target. |
| 587 "\n" | 584 |
| 588 " This target type allows you to create an object file that is (and can\n" | 585 This target type allows you to create an object file that is (and can only |
| 589 " only be) loaded and unloaded at runtime.\n" | 586 be) loaded and unloaded at runtime. |
| 590 "\n" | 587 |
| 591 " A loadable module will be specified on the linker line for targets\n" | 588 A loadable module will be specified on the linker line for targets listing |
| 592 " listing the loadable module in its \"deps\". If you don't want this\n" | 589 the loadable module in its "deps". If you don't want this (if you don't need |
| 593 " (if you don't need to dynamically load the library at runtime), then\n" | 590 to dynamically load the library at runtime), then you should use a |
| 594 " you should use a \"shared_library\" target type instead.\n" | 591 "shared_library" target type instead. |
| 595 "\n" | 592 |
| 596 "Variables\n" | 593 Variables |
| 597 "\n" | 594 )" |
| 598 CONFIG_VALUES_VARS_HELP | 595 CONFIG_VALUES_VARS_HELP |
| 599 DEPS_VARS | 596 DEPS_VARS |
| 600 DEPENDENT_CONFIG_VARS | 597 DEPENDENT_CONFIG_VARS |
| 601 GENERAL_TARGET_VARS; | 598 GENERAL_TARGET_VARS; |
| 602 | 599 |
| 603 Value RunLoadableModule(Scope* scope, | 600 Value RunLoadableModule(Scope* scope, |
| 604 const FunctionCallNode* function, | 601 const FunctionCallNode* function, |
| 605 const std::vector<Value>& args, | 602 const std::vector<Value>& args, |
| 606 BlockNode* block, | 603 BlockNode* block, |
| 607 Err* err) { | 604 Err* err) { |
| 608 return ExecuteGenericTarget(functions::kLoadableModule, scope, function, args, | 605 return ExecuteGenericTarget(functions::kLoadableModule, scope, function, args, |
| 609 block, err); | 606 block, err); |
| 610 } | 607 } |
| 611 | 608 |
| 612 // shared_library -------------------------------------------------------------- | 609 // shared_library -------------------------------------------------------------- |
| 613 | 610 |
| 614 const char kSharedLibrary[] = "shared_library"; | 611 const char kSharedLibrary[] = "shared_library"; |
| 615 const char kSharedLibrary_HelpShort[] = | 612 const char kSharedLibrary_HelpShort[] = |
| 616 "shared_library: Declare a shared library target."; | 613 "shared_library: Declare a shared library target."; |
| 617 const char kSharedLibrary_Help[] = | 614 const char kSharedLibrary_Help[] = |
| 618 "shared_library: Declare a shared library target.\n" | 615 R"(shared_library: Declare a shared library target. |
| 619 "\n" | 616 |
| 620 " A shared library will be specified on the linker line for targets\n" | 617 A shared library will be specified on the linker line for targets listing the |
| 621 " listing the shared library in its \"deps\". If you don't want this\n" | 618 shared library in its "deps". If you don't want this (say you dynamically |
| 622 " (say you dynamically load the library at runtime), then you should\n" | 619 load the library at runtime), then you should depend on the shared library |
| 623 " depend on the shared library via \"data_deps\" or, on Darwin\n" | 620 via "data_deps" or, on Darwin platforms, use a "loadable_module" target type |
| 624 " platforms, use a \"loadable_module\" target type instead.\n" | 621 instead. |
| 625 "\n" | 622 |
| 626 "Variables\n" | 623 Variables |
| 627 "\n" | 624 )" |
| 628 CONFIG_VALUES_VARS_HELP | 625 CONFIG_VALUES_VARS_HELP |
| 629 DEPS_VARS | 626 DEPS_VARS |
| 630 DEPENDENT_CONFIG_VARS | 627 DEPENDENT_CONFIG_VARS |
| 631 GENERAL_TARGET_VARS; | 628 GENERAL_TARGET_VARS; |
| 632 | 629 |
| 633 Value RunSharedLibrary(Scope* scope, | 630 Value RunSharedLibrary(Scope* scope, |
| 634 const FunctionCallNode* function, | 631 const FunctionCallNode* function, |
| 635 const std::vector<Value>& args, | 632 const std::vector<Value>& args, |
| 636 BlockNode* block, | 633 BlockNode* block, |
| 637 Err* err) { | 634 Err* err) { |
| 638 return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args, | 635 return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args, |
| 639 block, err); | 636 block, err); |
| 640 } | 637 } |
| 641 | 638 |
| 642 // source_set ------------------------------------------------------------------ | 639 // source_set ------------------------------------------------------------------ |
| 643 | 640 |
| 644 extern const char kSourceSet[] = "source_set"; | 641 extern const char kSourceSet[] = "source_set"; |
| 645 extern const char kSourceSet_HelpShort[] = | 642 extern const char kSourceSet_HelpShort[] = |
| 646 "source_set: Declare a source set target."; | 643 "source_set: Declare a source set target."; |
| 647 extern const char kSourceSet_Help[] = | 644 extern const char kSourceSet_Help[] = |
| 648 "source_set: Declare a source set target.\n" | 645 R"(source_set: Declare a source set target. |
| 649 "\n" | 646 |
| 650 " A source set is a collection of sources that get compiled, but are not\n" | 647 A source set is a collection of sources that get compiled, but are not linked |
| 651 " linked to produce any kind of library. Instead, the resulting object\n" | 648 to produce any kind of library. Instead, the resulting object files are |
| 652 " files are implicitly added to the linker line of all targets that\n" | 649 implicitly added to the linker line of all targets that depend on the source |
| 653 " depend on the source set.\n" | 650 set. |
| 654 "\n" | 651 |
| 655 " In most cases, a source set will behave like a static library, except\n" | 652 In most cases, a source set will behave like a static library, except no |
| 656 " no actual library file will be produced. This will make the build go\n" | 653 actual library file will be produced. This will make the build go a little |
| 657 " a little faster by skipping creation of a large static library, while\n" | 654 faster by skipping creation of a large static library, while maintaining the |
| 658 " maintaining the organizational benefits of focused build targets.\n" | 655 organizational benefits of focused build targets. |
| 659 "\n" | 656 |
| 660 " The main difference between a source set and a static library is\n" | 657 The main difference between a source set and a static library is around |
| 661 " around handling of exported symbols. Most linkers assume declaring\n" | 658 handling of exported symbols. Most linkers assume declaring a function |
| 662 " a function exported means exported from the static library. The linker\n" | 659 exported means exported from the static library. The linker can then do dead |
| 663 " can then do dead code elimination to delete code not reachable from\n" | 660 code elimination to delete code not reachable from exported functions. |
| 664 " exported functions.\n" | 661 |
| 665 "\n" | 662 A source set will not do this code elimination since there is no link step. |
| 666 " A source set will not do this code elimination since there is no link\n" | 663 This allows you to link many sources sets into a shared library and have the |
| 667 " step. This allows you to link many sources sets into a shared library\n" | 664 "exported symbol" notation indicate "export from the final shared library and |
| 668 " and have the \"exported symbol\" notation indicate \"export from the\n" | 665 not from the intermediate targets." There is no way to express this concept |
| 669 " final shared library and not from the intermediate targets.\" There is\n" | 666 when linking multiple static libraries into a shared library. |
| 670 " no way to express this concept when linking multiple static libraries\n" | 667 |
| 671 " into a shared library.\n" | 668 Variables |
| 672 "\n" | 669 )" |
| 673 "Variables\n" | |
| 674 "\n" | |
| 675 CONFIG_VALUES_VARS_HELP | 670 CONFIG_VALUES_VARS_HELP |
| 676 DEPS_VARS | 671 DEPS_VARS |
| 677 DEPENDENT_CONFIG_VARS | 672 DEPENDENT_CONFIG_VARS |
| 678 GENERAL_TARGET_VARS; | 673 GENERAL_TARGET_VARS; |
| 679 | 674 |
| 680 Value RunSourceSet(Scope* scope, | 675 Value RunSourceSet(Scope* scope, |
| 681 const FunctionCallNode* function, | 676 const FunctionCallNode* function, |
| 682 const std::vector<Value>& args, | 677 const std::vector<Value>& args, |
| 683 BlockNode* block, | 678 BlockNode* block, |
| 684 Err* err) { | 679 Err* err) { |
| 685 return ExecuteGenericTarget(functions::kSourceSet, scope, function, args, | 680 return ExecuteGenericTarget(functions::kSourceSet, scope, function, args, |
| 686 block, err); | 681 block, err); |
| 687 } | 682 } |
| 688 | 683 |
| 689 // static_library -------------------------------------------------------------- | 684 // static_library -------------------------------------------------------------- |
| 690 | 685 |
| 691 const char kStaticLibrary[] = "static_library"; | 686 const char kStaticLibrary[] = "static_library"; |
| 692 const char kStaticLibrary_HelpShort[] = | 687 const char kStaticLibrary_HelpShort[] = |
| 693 "static_library: Declare a static library target."; | 688 "static_library: Declare a static library target."; |
| 694 const char kStaticLibrary_Help[] = | 689 const char kStaticLibrary_Help[] = |
| 695 "static_library: Declare a static library target.\n" | 690 R"(static_library: Declare a static library target. |
| 696 "\n" | 691 |
| 697 " Make a \".a\" / \".lib\" file.\n" | 692 Make a ".a" / ".lib" file. |
| 698 "\n" | 693 |
| 699 " If you only need the static library for intermediate results in the\n" | 694 If you only need the static library for intermediate results in the build, |
| 700 " build, you should consider a source_set instead since it will skip\n" | 695 you should consider a source_set instead since it will skip the (potentially |
| 701 " the (potentially slow) step of creating the intermediate library file.\n" | 696 slow) step of creating the intermediate library file. |
| 702 "\n" | 697 |
| 703 "Variables\n" | 698 Variables |
| 704 "\n" | 699 |
| 705 "complete_static_lib\n" | 700 complete_static_lib |
| 701 )" |
| 706 CONFIG_VALUES_VARS_HELP | 702 CONFIG_VALUES_VARS_HELP |
| 707 DEPS_VARS | 703 DEPS_VARS |
| 708 DEPENDENT_CONFIG_VARS | 704 DEPENDENT_CONFIG_VARS |
| 709 GENERAL_TARGET_VARS; | 705 GENERAL_TARGET_VARS; |
| 710 | 706 |
| 711 Value RunStaticLibrary(Scope* scope, | 707 Value RunStaticLibrary(Scope* scope, |
| 712 const FunctionCallNode* function, | 708 const FunctionCallNode* function, |
| 713 const std::vector<Value>& args, | 709 const std::vector<Value>& args, |
| 714 BlockNode* block, | 710 BlockNode* block, |
| 715 Err* err) { | 711 Err* err) { |
| 716 return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args, | 712 return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args, |
| 717 block, err); | 713 block, err); |
| 718 } | 714 } |
| 719 | 715 |
| 720 // target --------------------------------------------------------------------- | 716 // target --------------------------------------------------------------------- |
| 721 | 717 |
| 722 const char kTarget[] = "target"; | 718 const char kTarget[] = "target"; |
| 723 const char kTarget_HelpShort[] = | 719 const char kTarget_HelpShort[] = |
| 724 "target: Declare an target with the given programmatic type."; | 720 "target: Declare an target with the given programmatic type."; |
| 725 const char kTarget_Help[] = | 721 const char kTarget_Help[] = |
| 726 "target: Declare an target with the given programmatic type.\n" | 722 R"(target: Declare an target with the given programmatic type. |
| 727 "\n" | 723 |
| 728 " target(target_type_string, target_name_string) { ... }\n" | 724 target(target_type_string, target_name_string) { ... } |
| 729 "\n" | 725 |
| 730 " The target() function is a way to invoke a built-in target or template\n" | 726 The target() function is a way to invoke a built-in target or template with a |
| 731 " with a type determined at runtime. This is useful for cases where the\n" | 727 type determined at runtime. This is useful for cases where the type of a |
| 732 " type of a target might not be known statically.\n" | 728 target might not be known statically. |
| 733 "\n" | 729 |
| 734 " Only templates and built-in target functions are supported for the\n" | 730 Only templates and built-in target functions are supported for the |
| 735 " target_type_string parameter. Arbitrary functions, configs, and\n" | 731 target_type_string parameter. Arbitrary functions, configs, and toolchains |
| 736 " toolchains are not supported.\n" | 732 are not supported. |
| 737 "\n" | 733 |
| 738 " The call:\n" | 734 The call: |
| 739 " target(\"source_set\", \"doom_melon\") {\n" | 735 target("source_set", "doom_melon") { |
| 740 " Is equivalent to:\n" | 736 Is equivalent to: |
| 741 " source_set(\"doom_melon\") {\n" | 737 source_set("doom_melon") { |
| 742 "\n" | 738 |
| 743 "Example\n" | 739 Example |
| 744 "\n" | 740 |
| 745 " if (foo_build_as_shared) {\n" | 741 if (foo_build_as_shared) { |
| 746 " my_type = \"shared_library\"\n" | 742 my_type = "shared_library" |
| 747 " } else {\n" | 743 } else { |
| 748 " my_type = \"source_set\"\n" | 744 my_type = "source_set" |
| 749 " }\n" | 745 } |
| 750 "\n" | 746 |
| 751 " target(my_type, \"foo\") {\n" | 747 target(my_type, "foo") { |
| 752 " ...\n" | 748 ... |
| 753 " }\n"; | 749 })"; |
| 754 Value RunTarget(Scope* scope, | 750 Value RunTarget(Scope* scope, |
| 755 const FunctionCallNode* function, | 751 const FunctionCallNode* function, |
| 756 const std::vector<Value>& args, | 752 const std::vector<Value>& args, |
| 757 BlockNode* block, | 753 BlockNode* block, |
| 758 Err* err) { | 754 Err* err) { |
| 759 if (args.size() != 2) { | 755 if (args.size() != 2) { |
| 760 *err = Err(function, "Expected two arguments.", "Try \"gn help target\"."); | 756 *err = Err(function, "Expected two arguments.", "Try \"gn help target\"."); |
| 761 return Value(); | 757 return Value(); |
| 762 } | 758 } |
| 763 | 759 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 774 const Template* templ = scope->GetTemplate(target_type); | 770 const Template* templ = scope->GetTemplate(target_type); |
| 775 if (templ) | 771 if (templ) |
| 776 return templ->Invoke(scope, function, target_type, sub_args, block, err); | 772 return templ->Invoke(scope, function, target_type, sub_args, block, err); |
| 777 | 773 |
| 778 // Otherwise, assume the target is a built-in target type. | 774 // Otherwise, assume the target is a built-in target type. |
| 779 return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args, | 775 return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args, |
| 780 block, err); | 776 block, err); |
| 781 } | 777 } |
| 782 | 778 |
| 783 } // namespace functions | 779 } // namespace functions |
| OLD | NEW |