Index: build/android/gyp/process_resources.py |
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py |
index f19754b16032e1e44a0443557921d443b527871c..f8971aa9d2a3da428846b907aa90ec4a55df6e4e 100755 |
--- a/build/android/gyp/process_resources.py |
+++ b/build/android/gyp/process_resources.py |
@@ -17,7 +17,6 @@ |
import re |
import shutil |
import sys |
-import xml.etree.ElementTree |
import generate_v14_compatible_resources |
@@ -144,42 +143,64 @@ |
return options |
-def CreateRJavaFiles(srcjar_dir, main_r_txt_file, packages, r_txt_files, |
- shared_resources): |
- assert len(packages) == len(r_txt_files), 'Need one R.txt file per package' |
- |
- # Map of (resource_type, name) -> Entry. |
- # Contains the correct values for resources. |
- all_resources = {} |
- for entry in _ParseTextSymbolsFile(main_r_txt_file): |
- all_resources[(entry.resource_type, entry.name)] = entry |
- |
- # Map of package_name->resource_type->entry |
- resources_by_package = ( |
- collections.defaultdict(lambda: collections.defaultdict(list))) |
- # Build the R.java files using each package's R.txt file, but replacing |
- # each entry's placeholder value with correct values from all_resources. |
- for package, r_txt_file in zip(packages, r_txt_files): |
- if package in resources_by_package: |
- raise Exception(('Package name "%s" appeared twice. All ' |
- 'android_resources() targets must use unique package ' |
- 'names, or no package name at all.') % package) |
- resources_by_type = resources_by_package[package] |
- # The sub-R.txt files have the wrong values at this point. Read them to |
- # figure out which entries belong to them, but use the values from the |
- # main R.txt file. |
+def CreateExtraRJavaFiles( |
+ r_dir, extra_packages, extra_r_text_files, shared_resources, include_all): |
+ if include_all: |
+ java_files = build_utils.FindInDirectory(r_dir, "R.java") |
+ if len(java_files) != 1: |
+ return |
+ r_java_file = java_files[0] |
+ r_java_contents = codecs.open(r_java_file, encoding='utf-8').read() |
+ |
+ for package in extra_packages: |
+ package_r_java_dir = os.path.join(r_dir, *package.split('.')) |
+ build_utils.MakeDirectory(package_r_java_dir) |
+ package_r_java_path = os.path.join(package_r_java_dir, 'R.java') |
+ new_r_java = re.sub(r'package [.\w]*;', u'package %s;' % package, |
+ r_java_contents) |
+ codecs.open(package_r_java_path, 'w', encoding='utf-8').write(new_r_java) |
+ else: |
+ if len(extra_packages) != len(extra_r_text_files): |
+ raise Exception('Need one R.txt file per extra package') |
+ |
+ r_txt_file = os.path.join(r_dir, 'R.txt') |
+ if not os.path.exists(r_txt_file): |
+ return |
+ |
+ # Map of (resource_type, name) -> Entry. |
+ # Contains the correct values for resources. |
+ all_resources = {} |
for entry in _ParseTextSymbolsFile(r_txt_file): |
- entry = all_resources[(entry.resource_type, entry.name)] |
- resources_by_type[entry.resource_type].append(entry) |
- |
- for package, resources_by_type in resources_by_package.iteritems(): |
- package_r_java_dir = os.path.join(srcjar_dir, *package.split('.')) |
- build_utils.MakeDirectory(package_r_java_dir) |
- package_r_java_path = os.path.join(package_r_java_dir, 'R.java') |
- java_file_contents = _CreateExtraRJavaFile( |
- package, resources_by_type, shared_resources) |
- with open(package_r_java_path, 'w') as f: |
- f.write(java_file_contents) |
+ all_resources[(entry.resource_type, entry.name)] = entry |
+ |
+ # Map of package_name->resource_type->entry |
+ resources_by_package = ( |
+ collections.defaultdict(lambda: collections.defaultdict(list))) |
+ # Build the R.java files using each package's R.txt file, but replacing |
+ # each entry's placeholder value with correct values from all_resources. |
+ for package, r_text_file in zip(extra_packages, extra_r_text_files): |
+ if not os.path.exists(r_text_file): |
+ continue |
+ if package in resources_by_package: |
+ raise Exception(('Package name "%s" appeared twice. All ' |
+ 'android_resources() targets must use unique package ' |
+ 'names, or no package name at all.') % package) |
+ resources_by_type = resources_by_package[package] |
+ # The sub-R.txt files have the wrong values at this point. Read them to |
+ # figure out which entries belong to them, but use the values from the |
+ # main R.txt file. |
+ for entry in _ParseTextSymbolsFile(r_text_file): |
+ entry = all_resources[(entry.resource_type, entry.name)] |
+ resources_by_type[entry.resource_type].append(entry) |
+ |
+ for package, resources_by_type in resources_by_package.iteritems(): |
+ package_r_java_dir = os.path.join(r_dir, *package.split('.')) |
+ build_utils.MakeDirectory(package_r_java_dir) |
+ package_r_java_path = os.path.join(package_r_java_dir, 'R.java') |
+ java_file_contents = _CreateExtraRJavaFile( |
+ package, resources_by_type, shared_resources) |
+ with open(package_r_java_path, 'w') as f: |
+ f.write(java_file_contents) |
def _ParseTextSymbolsFile(path): |
@@ -320,11 +341,6 @@ |
build_utils.MergeZips(output_path, zip_files, path_transform=path_transform) |
-def _ExtractPackageFromManifest(manifest_path): |
- doc = xml.etree.ElementTree.parse(manifest_path) |
- return doc.getroot().get('package') |
- |
- |
def _OnStaleMd5(options): |
aapt = options.aapt_path |
with build_utils.TempDir() as temp_dir: |
@@ -335,8 +351,6 @@ |
gen_dir = os.path.join(temp_dir, 'gen') |
build_utils.MakeDirectory(gen_dir) |
- r_txt_path = os.path.join(gen_dir, 'R.txt') |
- srcjar_dir = os.path.join(temp_dir, 'java') |
input_resource_dirs = options.resource_dirs |
@@ -368,72 +382,34 @@ |
'--no-version-vectors', |
'-I', options.android_sdk_jar, |
'--output-text-symbols', gen_dir, |
- '-J', gen_dir, # Required for R.txt generation. |
+ '-J', gen_dir, |
'--ignore-assets', build_utils.AAPT_IGNORE_PATTERN] |
- |
- # aapt supports only the "--include-all-resources" mode, where each R.java |
- # file ends up with all symbols, rather than only those that it had at the |
- # time it was originally generated. This subtle difference makes no |
- # difference when compiling, but can lead to increased unused symbols in the |
- # resulting R.class files. |
- # TODO(agrieve): See if proguard makes this difference actually translate |
- # into a size difference. If not, we can delete all of our custom R.java |
- # template code above (and make include_all_resources the default). |
- if options.include_all_resources: |
- srcjar_dir = gen_dir |
- if options.extra_res_packages: |
- colon_separated = ':'.join(options.extra_res_packages) |
- package_command += ['--extra-packages', colon_separated] |
- if options.non_constant_id: |
- package_command.append('--non-constant-id') |
- if options.custom_package: |
- package_command += ['--custom-package', options.custom_package] |
- if options.shared_resources: |
- package_command.append('--shared-lib') |
- if options.app_as_shared_lib: |
- package_command.append('--app-as-shared-lib') |
for d in input_resource_dirs: |
package_command += ['-S', d] |
- # Adding all dependencies as sources is necessary for @type/foo references |
- # to symbols within dependencies to resolve. However, it has the side-effect |
- # that all Java symbols from dependencies are copied into the new R.java. |
- # E.g.: It enables an arguably incorrect usage of |
- # "mypackage.R.id.lib_symbol" where "libpackage.R.id.lib_symbol" would be |
- # more correct. This is just how Android works. |
for d in dep_subdirs: |
package_command += ['-S', d] |
+ if options.non_constant_id: |
+ package_command.append('--non-constant-id') |
+ if options.custom_package: |
+ package_command += ['--custom-package', options.custom_package] |
if options.proguard_file: |
package_command += ['-G', options.proguard_file] |
+ if options.shared_resources: |
+ package_command.append('--shared-lib') |
+ if options.app_as_shared_lib: |
+ package_command.append('--app-as-shared-lib') |
build_utils.CheckOutput(package_command, print_stderr=False) |
- # When an empty res/ directory is passed, aapt does not write an R.txt. |
- if not os.path.exists(r_txt_path): |
- build_utils.Touch(r_txt_path) |
- |
- if not options.include_all_resources: |
- packages = list(options.extra_res_packages) |
- r_txt_files = list(options.extra_r_text_files) |
- |
- cur_package = options.custom_package |
- if not options.custom_package: |
- cur_package = _ExtractPackageFromManifest(options.android_manifest) |
- |
- # Don't create a .java file for the current resource target when: |
- # - no package name was provided (either by manifest or build rules), |
- # - there was already a dependent android_resources() with the same |
- # package (occurs mostly when an apk target and resources target share |
- # an AndroidManifest.xml) |
- if cur_package != 'dummy.package' and cur_package not in packages: |
- packages.append(cur_package) |
- r_txt_files.append(r_txt_path) |
- |
- if packages: |
- shared_resources = options.shared_resources or options.app_as_shared_lib |
- CreateRJavaFiles(srcjar_dir, r_txt_path, packages, r_txt_files, |
- shared_resources) |
+ if options.extra_res_packages: |
+ CreateExtraRJavaFiles( |
+ gen_dir, |
+ options.extra_res_packages, |
+ options.extra_r_text_files, |
+ options.shared_resources or options.app_as_shared_lib, |
+ options.include_all_resources) |
# This is the list of directories with resources to put in the final .zip |
# file. The order of these is important so that crunched/v14 resources |
@@ -459,12 +435,16 @@ |
if options.R_dir: |
build_utils.DeleteDirectory(options.R_dir) |
- shutil.copytree(srcjar_dir, options.R_dir) |
+ shutil.copytree(gen_dir, options.R_dir) |
else: |
- build_utils.ZipDir(options.srcjar_out, srcjar_dir) |
+ build_utils.ZipDir(options.srcjar_out, gen_dir) |
if options.r_text_out: |
- shutil.copyfile(r_txt_path, options.r_text_out) |
+ r_text_path = os.path.join(gen_dir, 'R.txt') |
+ if os.path.exists(r_text_path): |
+ shutil.copyfile(r_text_path, options.r_text_out) |
+ else: |
+ open(options.r_text_out, 'w').close() |
def main(args): |
@@ -497,7 +477,7 @@ |
options.android_sdk_jar, |
] |
input_paths.extend(options.dependencies_res_zips) |
- input_paths.extend(options.extra_r_text_files) |
+ input_paths.extend(p for p in options.extra_r_text_files if os.path.exists(p)) |
resource_names = [] |
for resource_dir in options.resource_dirs: |