OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Process Android resources to generate R.java, and prepare for packaging. | 7 """Process Android resources to generate R.java, and prepare for packaging. |
8 | 8 |
9 This will crunch images and generate v14 compatible resources | 9 This will crunch images and generate v14 compatible resources |
10 (see generate_v14_compatible_resources.py). | 10 (see generate_v14_compatible_resources.py). |
(...skipping 15 matching lines...) Expand all Loading... |
26 sys.path.insert(1, | 26 sys.path.insert(1, |
27 os.path.join(os.path.dirname(__file__), '../../../third_party')) | 27 os.path.join(os.path.dirname(__file__), '../../../third_party')) |
28 from jinja2 import Template # pylint: disable=F0401 | 28 from jinja2 import Template # pylint: disable=F0401 |
29 | 29 |
30 | 30 |
31 # Represents a line from a R.txt file. | 31 # Represents a line from a R.txt file. |
32 TextSymbolsEntry = collections.namedtuple('RTextEntry', | 32 TextSymbolsEntry = collections.namedtuple('RTextEntry', |
33 ('java_type', 'resource_type', 'name', 'value')) | 33 ('java_type', 'resource_type', 'name', 'value')) |
34 | 34 |
35 | 35 |
36 def ParseArgs(args): | 36 def _ParseArgs(args): |
37 """Parses command line options. | 37 """Parses command line options. |
38 | 38 |
39 Returns: | 39 Returns: |
40 An options object as from optparse.OptionsParser.parse_args() | 40 An options object as from optparse.OptionsParser.parse_args() |
41 """ | 41 """ |
42 parser = optparse.OptionParser() | 42 parser = optparse.OptionParser() |
43 build_utils.AddDepfileOption(parser) | 43 build_utils.AddDepfileOption(parser) |
44 | 44 |
45 parser.add_option('--android-sdk', help='path to the Android SDK folder') | 45 parser.add_option('--android-sdk', help='path to the Android SDK folder') |
46 parser.add_option('--aapt-path', | 46 parser.add_option('--aapt-path', |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 help='Include every resource ID in every generated R.java file ' | 96 help='Include every resource ID in every generated R.java file ' |
97 '(ignoring R.txt).') | 97 '(ignoring R.txt).') |
98 | 98 |
99 parser.add_option( | 99 parser.add_option( |
100 '--all-resources-zip-out', | 100 '--all-resources-zip-out', |
101 help='Path for output of all resources. This includes resources in ' | 101 help='Path for output of all resources. This includes resources in ' |
102 'dependencies.') | 102 'dependencies.') |
103 | 103 |
104 parser.add_option('--stamp', help='File to touch on success') | 104 parser.add_option('--stamp', help='File to touch on success') |
105 | 105 |
106 (options, args) = parser.parse_args(args) | 106 options, positional_args = parser.parse_args(args) |
107 | 107 |
108 if args: | 108 if positional_args: |
109 parser.error('No positional arguments should be given.') | 109 parser.error('No positional arguments should be given.') |
110 | 110 |
111 # Check that required options have been provided. | 111 # Check that required options have been provided. |
112 required_options = ( | 112 required_options = ( |
113 'android_sdk', | 113 'android_sdk', |
114 'aapt_path', | 114 'aapt_path', |
115 'android_manifest', | 115 'android_manifest', |
116 'dependencies_res_zips', | 116 'dependencies_res_zips', |
117 'resource_dirs', | 117 'resource_dirs', |
118 'resource_zip_out', | 118 'resource_zip_out', |
119 ) | 119 ) |
120 build_utils.CheckOptions(options, parser, required=required_options) | 120 build_utils.CheckOptions(options, parser, required=required_options) |
121 | 121 |
122 if (options.R_dir is None) == (options.srcjar_out is None): | 122 if (options.R_dir is None) == (options.srcjar_out is None): |
123 raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.') | 123 raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.') |
124 | 124 |
| 125 options.resource_dirs = build_utils.ParseGypList(options.resource_dirs) |
| 126 options.dependencies_res_zips = ( |
| 127 build_utils.ParseGypList(options.dependencies_res_zips)) |
| 128 |
| 129 # Don't use [] as default value since some script explicitly pass "". |
| 130 if options.extra_res_packages: |
| 131 options.extra_res_packages = ( |
| 132 build_utils.ParseGypList(options.extra_res_packages)) |
| 133 else: |
| 134 options.extra_res_packages = [] |
| 135 |
| 136 if options.extra_r_text_files: |
| 137 options.extra_r_text_files = ( |
| 138 build_utils.ParseGypList(options.extra_r_text_files)) |
| 139 else: |
| 140 options.extra_r_text_files = [] |
| 141 |
125 return options | 142 return options |
126 | 143 |
127 | 144 |
128 def CreateExtraRJavaFiles( | 145 def CreateExtraRJavaFiles( |
129 r_dir, extra_packages, extra_r_text_files, shared_resources, include_all): | 146 r_dir, extra_packages, extra_r_text_files, shared_resources, include_all): |
130 if include_all: | 147 if include_all: |
131 java_files = build_utils.FindInDirectory(r_dir, "R.java") | 148 java_files = build_utils.FindInDirectory(r_dir, "R.java") |
132 if len(java_files) != 1: | 149 if len(java_files) != 1: |
133 return | 150 return |
134 r_java_file = java_files[0] | 151 r_java_file = java_files[0] |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 # of the form 0, 1, ..., then each subdirectory will be passed to aapt as a | 333 # of the form 0, 1, ..., then each subdirectory will be passed to aapt as a |
317 # resources directory. While some resources just clobber others (image files, | 334 # resources directory. While some resources just clobber others (image files, |
318 # etc), other resources (particularly .xml files) need to be more | 335 # etc), other resources (particularly .xml files) need to be more |
319 # intelligently merged. That merging is left up to aapt. | 336 # intelligently merged. That merging is left up to aapt. |
320 def path_transform(name, src_zip): | 337 def path_transform(name, src_zip): |
321 return '%d/%s' % (zip_files.index(src_zip), name) | 338 return '%d/%s' % (zip_files.index(src_zip), name) |
322 | 339 |
323 build_utils.MergeZips(output_path, zip_files, path_transform=path_transform) | 340 build_utils.MergeZips(output_path, zip_files, path_transform=path_transform) |
324 | 341 |
325 | 342 |
326 def main(): | 343 def _OnStaleMd5(options): |
327 args = build_utils.ExpandFileArgs(sys.argv[1:]) | |
328 | |
329 options = ParseArgs(args) | |
330 android_jar = os.path.join(options.android_sdk, 'android.jar') | 344 android_jar = os.path.join(options.android_sdk, 'android.jar') |
331 aapt = options.aapt_path | 345 aapt = options.aapt_path |
332 | |
333 input_files = [] | |
334 | |
335 with build_utils.TempDir() as temp_dir: | 346 with build_utils.TempDir() as temp_dir: |
336 deps_dir = os.path.join(temp_dir, 'deps') | 347 deps_dir = os.path.join(temp_dir, 'deps') |
337 build_utils.MakeDirectory(deps_dir) | 348 build_utils.MakeDirectory(deps_dir) |
338 v14_dir = os.path.join(temp_dir, 'v14') | 349 v14_dir = os.path.join(temp_dir, 'v14') |
339 build_utils.MakeDirectory(v14_dir) | 350 build_utils.MakeDirectory(v14_dir) |
340 | 351 |
341 gen_dir = os.path.join(temp_dir, 'gen') | 352 gen_dir = os.path.join(temp_dir, 'gen') |
342 build_utils.MakeDirectory(gen_dir) | 353 build_utils.MakeDirectory(gen_dir) |
343 | 354 |
344 input_resource_dirs = build_utils.ParseGypList(options.resource_dirs) | 355 input_resource_dirs = options.resource_dirs |
345 | 356 |
346 if not options.v14_skip: | 357 if not options.v14_skip: |
347 for resource_dir in input_resource_dirs: | 358 for resource_dir in input_resource_dirs: |
348 generate_v14_compatible_resources.GenerateV14Resources( | 359 generate_v14_compatible_resources.GenerateV14Resources( |
349 resource_dir, | 360 resource_dir, |
350 v14_dir) | 361 v14_dir) |
351 | 362 |
352 dep_zips = build_utils.ParseGypList(options.dependencies_res_zips) | 363 dep_zips = options.dependencies_res_zips |
353 input_files += dep_zips | |
354 dep_subdirs = [] | 364 dep_subdirs = [] |
355 for z in dep_zips: | 365 for z in dep_zips: |
356 subdir = os.path.join(deps_dir, os.path.basename(z)) | 366 subdir = os.path.join(deps_dir, os.path.basename(z)) |
357 if os.path.exists(subdir): | 367 if os.path.exists(subdir): |
358 raise Exception('Resource zip name conflict: ' + os.path.basename(z)) | 368 raise Exception('Resource zip name conflict: ' + os.path.basename(z)) |
359 build_utils.ExtractAll(z, path=subdir) | 369 build_utils.ExtractAll(z, path=subdir) |
360 dep_subdirs.append(subdir) | 370 dep_subdirs.append(subdir) |
361 | 371 |
362 # Generate R.java. This R.java contains non-final constants and is used only | 372 # Generate R.java. This R.java contains non-final constants and is used only |
363 # while compiling the library jar (e.g. chromium_content.jar). When building | 373 # while compiling the library jar (e.g. chromium_content.jar). When building |
(...skipping 24 matching lines...) Expand all Loading... |
388 package_command += ['-G', options.proguard_file] | 398 package_command += ['-G', options.proguard_file] |
389 if options.shared_resources: | 399 if options.shared_resources: |
390 package_command.append('--shared-lib') | 400 package_command.append('--shared-lib') |
391 if options.app_as_shared_lib: | 401 if options.app_as_shared_lib: |
392 package_command.append('--app-as-shared-lib') | 402 package_command.append('--app-as-shared-lib') |
393 build_utils.CheckOutput(package_command, print_stderr=False) | 403 build_utils.CheckOutput(package_command, print_stderr=False) |
394 | 404 |
395 if options.extra_res_packages: | 405 if options.extra_res_packages: |
396 CreateExtraRJavaFiles( | 406 CreateExtraRJavaFiles( |
397 gen_dir, | 407 gen_dir, |
398 build_utils.ParseGypList(options.extra_res_packages), | 408 options.extra_res_packages, |
399 build_utils.ParseGypList(options.extra_r_text_files), | 409 options.extra_r_text_files, |
400 options.shared_resources, | 410 options.shared_resources, |
401 options.include_all_resources) | 411 options.include_all_resources) |
402 | 412 |
403 # This is the list of directories with resources to put in the final .zip | 413 # This is the list of directories with resources to put in the final .zip |
404 # file. The order of these is important so that crunched/v14 resources | 414 # file. The order of these is important so that crunched/v14 resources |
405 # override the normal ones. | 415 # override the normal ones. |
406 zip_resource_dirs = input_resource_dirs + [v14_dir] | 416 zip_resource_dirs = input_resource_dirs + [v14_dir] |
407 | 417 |
408 base_crunch_dir = os.path.join(temp_dir, 'crunch') | 418 base_crunch_dir = os.path.join(temp_dir, 'crunch') |
409 | 419 |
(...skipping 18 matching lines...) Expand all Loading... |
428 else: | 438 else: |
429 build_utils.ZipDir(options.srcjar_out, gen_dir) | 439 build_utils.ZipDir(options.srcjar_out, gen_dir) |
430 | 440 |
431 if options.r_text_out: | 441 if options.r_text_out: |
432 r_text_path = os.path.join(gen_dir, 'R.txt') | 442 r_text_path = os.path.join(gen_dir, 'R.txt') |
433 if os.path.exists(r_text_path): | 443 if os.path.exists(r_text_path): |
434 shutil.copyfile(r_text_path, options.r_text_out) | 444 shutil.copyfile(r_text_path, options.r_text_out) |
435 else: | 445 else: |
436 open(options.r_text_out, 'w').close() | 446 open(options.r_text_out, 'w').close() |
437 | 447 |
438 if options.depfile: | |
439 input_files += build_utils.GetPythonDependencies() | |
440 build_utils.WriteDepfile(options.depfile, input_files) | |
441 | 448 |
442 if options.stamp: | 449 def main(args): |
443 build_utils.Touch(options.stamp) | 450 args = build_utils.ExpandFileArgs(args) |
| 451 options = _ParseArgs(args) |
| 452 |
| 453 possible_output_paths = [ |
| 454 options.resource_zip_out, |
| 455 options.all_resources_zip_out, |
| 456 options.proguard_file, |
| 457 options.r_text_out, |
| 458 options.srcjar_out, |
| 459 ] |
| 460 output_paths = [x for x in possible_output_paths if x] |
| 461 |
| 462 # List python deps in input_strings rather than input_paths since the contents |
| 463 # of them does not change what gets written to the depsfile. |
| 464 input_strings = options.extra_res_packages + [ |
| 465 options.aapt_path, |
| 466 options.android_sdk, |
| 467 options.app_as_shared_lib, |
| 468 options.custom_package, |
| 469 options.include_all_resources, |
| 470 options.non_constant_id, |
| 471 options.shared_resources, |
| 472 options.v14_skip, |
| 473 ] |
| 474 |
| 475 input_paths = [ options.android_manifest ] |
| 476 input_paths.extend(options.dependencies_res_zips) |
| 477 input_paths.extend(p for p in options.extra_r_text_files if os.path.exists(p)) |
| 478 |
| 479 for d in options.resource_dirs: |
| 480 for root, _, filenames in os.walk(d): |
| 481 input_paths.extend(os.path.join(root, f) for f in filenames) |
| 482 |
| 483 build_utils.CallAndWriteDepfileIfStale( |
| 484 lambda: _OnStaleMd5(options), |
| 485 options, |
| 486 input_paths=input_paths, |
| 487 input_strings=input_strings, |
| 488 output_paths=output_paths, |
| 489 # TODO(agrieve): Remove R_dir when it's no longer used (used only by GYP). |
| 490 force=options.R_dir) |
444 | 491 |
445 | 492 |
446 if __name__ == '__main__': | 493 if __name__ == '__main__': |
447 main() | 494 main(sys.argv[1:]) |
OLD | NEW |