diff --git a/build/android/ant/apk-obfuscate.xml b/build/android/ant/apk-obfuscate.xml deleted file mode 100644 index 094c9881ec0ce1..00000000000000 --- a/build/android/ant/apk-obfuscate.xml +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -include "${proguard.configcmd}" - -injars ${project.all.classes.value} - -outjars "${obfuscated.jar.abs.file}" - -libraryjars ${project.target.classpath.value} - -dump "${obfuscate.absolute.dir}/dump.txt" - -printseeds "${obfuscate.absolute.dir}/seeds.txt" - -printusage "${obfuscate.absolute.dir}/usage.txt" - -printmapping "${obfuscate.absolute.dir}/mapping.txt" - - - - - - diff --git a/build/android/gyp/apk_obfuscate.py b/build/android/gyp/apk_obfuscate.py new file mode 100755 index 00000000000000..1e2eccf1745107 --- /dev/null +++ b/build/android/gyp/apk_obfuscate.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Generates the obfuscated jar and test jar for an apk. + +If proguard is not enabled or 'Release' is not in the configuration name, +obfuscation will be a no-op. +""" + +import fnmatch +import optparse +import os +import sys +import zipfile + +from util import build_utils + +def ParseArgs(argv): + parser = optparse.OptionParser() + parser.add_option('--android-sdk', help='path to the Android SDK folder') + parser.add_option('--android-sdk-tools', + help='path to the Android SDK build tools folder') + parser.add_option('--android-sdk-jar', + help='path to Android SDK\'s android.jar') + parser.add_option('--proguard-jar-path', + help='Path to proguard.jar in the sdk') + + parser.add_option('--input-jars-paths', + help='Path to jars to include in obfuscated jar') + + parser.add_option('--proguard-config-files', + help='Paths to proguard config files') + + parser.add_option('--configuration-name', + help='Gyp configuration name (i.e. Debug, Release)') + parser.add_option('--proguard-enabled', action='store_true', + help='Set if proguard is enabled for this target.') + + parser.add_option('--obfuscated-jar-path', + help='Output path for obfuscated jar.') + + parser.add_option('--testapp', action='store_true', + help='Set this if building an instrumentation test apk') + parser.add_option('--test-jar-path', + help='Output path for jar containing all the test apk\'s ' + 'code.') + + parser.add_option('--stamp', help='File to touch on success') + + (options, args) = parser.parse_args(argv) + + if args: + parser.error('No positional arguments should be given. ' + str(args)) + + # Check that required options have been provided. + required_options = ( + 'android_sdk', + 'android_sdk_tools', + 'android_sdk_jar', + 'proguard_jar_path', + 'input_jars_paths', + 'configuration_name', + 'obfuscated_jar_path', + ) + build_utils.CheckOptions(options, parser, required=required_options) + + return options, args + + +def main(argv): + options, _ = ParseArgs(argv) + + library_classpath = [options.android_sdk_jar] + javac_custom_classpath = build_utils.ParseGypList(options.input_jars_paths) + + dependency_class_filters = [ + '*R.class', '*R$*.class', '*Manifest.class', '*BuildConfig.class'] + + def DependencyClassFilter(name): + for name_filter in dependency_class_filters: + if fnmatch.fnmatch(name, name_filter): + return False + return True + + if options.testapp: + with zipfile.ZipFile(options.test_jar_path, 'w') as test_jar: + for jar in build_utils.ParseGypList(options.input_jars_paths): + with zipfile.ZipFile(jar, 'r') as jar_zip: + for name in filter(DependencyClassFilter, jar_zip.namelist()): + with jar_zip.open(name) as zip_entry: + test_jar.writestr(name, zip_entry.read()) + + if options.configuration_name == 'Release' and options.proguard_enabled: + proguard_project_classpath = javac_custom_classpath + + proguard_cmd = [ + 'java', '-jar', options.proguard_jar_path, + '-forceprocessing', + '-injars', ':'.join(proguard_project_classpath), + '-libraryjars', ':'.join(library_classpath), + '-outjars', options.obfuscated_jar_path, + '-dump', options.obfuscated_jar_path + '.dump', + '-printseeds', options.obfuscated_jar_path + '.seeds', + '-printusage', options.obfuscated_jar_path + '.usage', + '-printmapping', options.obfuscated_jar_path + '.mapping', + ] + + for proguard_file in build_utils.ParseGypList( + options.proguard_config_files): + proguard_cmd += ['-include', proguard_file] + + build_utils.CheckOutput(proguard_cmd) + else: + output_files = [ + options.obfuscated_jar_path, + options.obfuscated_jar_path + '.dump', + options.obfuscated_jar_path + '.seeds', + options.obfuscated_jar_path + '.usage', + options.obfuscated_jar_path + '.mapping'] + for f in output_files: + if os.path.exists(f): + os.remove(f) + build_utils.Touch(f) + + if options.stamp: + build_utils.Touch(options.stamp) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/build/apk_fake_jar.gypi b/build/apk_fake_jar.gypi index 2787691c342335..128b84cc2fa2b3 100644 --- a/build/apk_fake_jar.gypi +++ b/build/apk_fake_jar.gypi @@ -12,14 +12,4 @@ 'library_dexed_jars_paths': ['>(apk_output_jar_path)'], }, }, - # Add an action with the appropriate output. This allows the generated - # buildfiles to determine which target the output corresponds to. - 'actions': [ - { - 'action_name': 'fake_generate_jar', - 'inputs': [], - 'outputs': ['>(apk_output_jar_path)'], - 'action': [], - }, - ], } diff --git a/build/java_apk.gypi b/build/java_apk.gypi index b654ad88bddba7..9e2b937a39be78 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi @@ -98,6 +98,7 @@ 'jar_excluded_classes': [], 'jar_path': '<(PRODUCT_DIR)/lib.java/<(jar_name)', 'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar', + 'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar', 'dex_path': '<(intermediate_dir)/classes.dex', 'emma_device_jar': '<(android_sdk_root)/tools/lib/emma_device.jar', 'android_manifest_path%': '<(java_in_dir)/AndroidManifest.xml', @@ -585,6 +586,7 @@ ], 'outputs': [ '<(jar_stamp)', + '<(jar_path)', ], 'action': [ 'python', '<(DEPTH)/build/android/gyp/jar.py', @@ -595,43 +597,72 @@ ] }, { - 'action_name': 'ant_obfuscate_<(_target_name)', + 'action_name': 'obfuscate_<(_target_name)', 'message': 'Obfuscating <(_target_name)', + 'variables': { + 'additional_obfuscate_options': [], + 'proguard_out_dir': '<(intermediate_dir)/proguard', + 'proguard_input_jar_paths': [ + '>@(input_jars_paths)', + '<(jar_path)', + ], + 'conditions': [ + ['is_test_apk == 1', { + 'additional_obfuscate_options': [ + '--testapp', + ], + }], + ['proguard_enabled == "true"', { + 'additional_obfuscate_options': [ + '--proguard-enabled', + ], + }], + ], + }, + 'conditions': [ + ['is_test_apk == 1', { + 'outputs': [ + '<(test_jar_path)', + ], + }], + ], 'inputs': [ - '<(DEPTH)/build/android/ant/apk-obfuscate.xml', + '<(DEPTH)/build/android/gyp/apk_obfuscate.py', '<(DEPTH)/build/android/gyp/util/build_utils.py', - '<(DEPTH)/build/android/gyp/ant.py', - '<(android_manifest_path)', '>@(proguard_flags_paths)', - '<(instr_stamp)', + '>@(proguard_input_jar_paths)', ], 'outputs': [ # This lists obfuscate_stamp instead of obfuscated_jar_path because # ant only writes the latter if the md5 of the inputs changes. '<(obfuscate_stamp)', + + # In non-Release builds, these paths will all be empty files. + '<(obfuscated_jar_path)', + '<(obfuscated_jar_path).dump', + '<(obfuscated_jar_path).seeds', + '<(obfuscated_jar_path).mapping', + '<(obfuscated_jar_path).usage', ], 'action': [ - 'python', '<(DEPTH)/build/android/gyp/ant.py', - '-quiet', - '-DANDROID_MANIFEST=<(android_manifest_path)', - '-DANDROID_SDK_JAR=<(android_sdk_jar)', - '-DANDROID_SDK_ROOT=<(android_sdk_root)', - '-DANDROID_SDK_VERSION=<(android_sdk_version)', - '-DANDROID_SDK_TOOLS=<(android_sdk_tools)', - '-DAPK_NAME=<(apk_name)', - '-DCONFIGURATION_NAME=<(CONFIGURATION_NAME)', - '-DINPUT_JARS_PATHS=>(input_jars_paths)', - '-DIS_TEST_APK=<(is_test_apk)', - '-DOBFUSCATED_JAR_PATH=<(obfuscated_jar_path)', - '-DOUT_DIR=<(intermediate_dir)', - '-DPROGUARD_ENABLED=<(proguard_enabled)', - '-DPROGUARD_FLAGS=<(proguard_flags_paths)', - '-DTEST_JAR_PATH=<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar', + 'python', '<(DEPTH)/build/android/gyp/apk_obfuscate.py', - '-DSTAMP=<(obfuscate_stamp)', - '-Dbasedir=.', - '-buildfile', - '<(DEPTH)/build/android/ant/apk-obfuscate.xml', + '--configuration-name', '<(CONFIGURATION_NAME)', + + '--android-sdk', '<(android_sdk)', + '--android-sdk-tools', '<(android_sdk_tools)', + '--android-sdk-jar', '<(android_sdk_jar)', + + '--input-jars-paths=>(proguard_input_jar_paths)', + '--test-jar-path', '<(test_jar_path)', + '--obfuscated-jar-path', '<(obfuscated_jar_path)', + + '--proguard-jar-path', '<(android_sdk_root)/tools/proguard/lib/proguard.jar', + + '--proguard-config-files=<(proguard_flags_paths)', + '--stamp', '<(obfuscate_stamp)', + + '<@(additional_obfuscate_options)', ], }, {