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 |