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