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 |