Use copied r8.jar in run_on_as_app.py
This ensures that all compilations from a single execution of run_on_as_app.py will use the same r8.jar. This is currently not guaranteed if build/libs/r8.jar is rebuilt as part of development.
Change-Id: Ie3f4cf0e2c9d9010c872d5b2d46ccaff9812d7e7
diff --git a/tools/run_on_as_app.py b/tools/run_on_as_app.py
index fcd0a76..128b6e3 100755
--- a/tools/run_on_as_app.py
+++ b/tools/run_on_as_app.py
@@ -8,9 +8,9 @@
import gradle
import os
import optparse
+import shutil
import subprocess
import sys
-import tempfile
import time
import utils
import zipfile
@@ -36,6 +36,7 @@
'git_repo': 'https://github.com/christofferqa/AnExplorer',
'flavor': 'googleMobilePro',
'signed-apk-name': 'AnExplorer-googleMobileProRelease-4.0.3.apk',
+ 'min_sdk': 17
},
'AntennaPod': {
'app_id': 'de.danoeh.antennapod',
@@ -127,9 +128,18 @@
dex_size += z.getinfo(filename).file_size
return dex_size
-def IsBuiltWithR8(apk):
- script = os.path.join(utils.TOOLS_DIR, 'extractmarker.py')
- return '~~R8' in subprocess.check_output(['python', script, apk]).strip()
+def IsBuiltWithR8(apk, temp_dir):
+ r8_jar = os.path.join(temp_dir, 'r8.jar')
+
+ # Use the copy of r8.jar if it is there.
+ if os.path.isfile(r8_jar):
+ cmd = ['java', '-ea', '-jar', r8_jar, 'extractmarker', apk]
+ else:
+ script = os.path.join(utils.TOOLS_DIR, 'extractmarker.py')
+ cmd = ['python', script, apk]
+
+ utils.PrintCmd(cmd)
+ return '~~R8' in subprocess.check_output(cmd).strip()
def IsMinifiedR8(shrinker):
return shrinker == 'r8-minified' or shrinker == 'r8full-minified'
@@ -196,7 +206,7 @@
else:
return True
-def GetResultsForApp(app, config, options):
+def GetResultsForApp(app, config, options, temp_dir):
git_repo = config['git_repo']
# Checkout and build in the build directory.
@@ -221,13 +231,13 @@
result['status'] = 'success'
result_per_shrinker = BuildAppWithSelectedShrinkers(
- app, config, options, checkout_dir)
+ app, config, options, checkout_dir, temp_dir)
for shrinker, shrinker_result in result_per_shrinker.iteritems():
result[shrinker] = shrinker_result
return result
-def BuildAppWithSelectedShrinkers(app, config, options, checkout_dir):
+def BuildAppWithSelectedShrinkers(app, config, options, checkout_dir, temp_dir):
result_per_shrinker = {}
with utils.ChangedWorkingDirectory(checkout_dir):
@@ -242,7 +252,7 @@
out_dir = os.path.join(checkout_dir, 'out', shrinker)
(apk_dest, profile_dest_dir, proguard_config_file) = \
BuildAppWithShrinker(app, config, shrinker, checkout_dir, out_dir,
- options)
+ temp_dir, options)
dex_size = ComputeSizeOfDexFilesInApk(apk_dest)
result['apk_dest'] = apk_dest,
result['build_status'] = 'success'
@@ -278,7 +288,7 @@
}
(apk_dest, profile_dest_dir, ext_proguard_config_file) = \
BuildAppWithShrinker(app, config, shrinker, checkout_dir, out_dir,
- options, extra_env_vars)
+ temp_dir, options, extra_env_vars)
dex_size = ComputeSizeOfDexFilesInApk(apk_dest)
recompilation_result = {
'apk_dest': apk_dest,
@@ -305,7 +315,7 @@
checkout_dir, 'out', shrinker, 'app-release-{}.apk'.format(i))
RebuildAppWithShrinker(
previous_apk, recompiled_apk_dest, ext_proguard_config_file,
- shrinker, min_sdk, compile_sdk)
+ shrinker, min_sdk, compile_sdk, temp_dir)
recompilation_result = {
'apk_dest': recompiled_apk_dest,
'build_status': 'success',
@@ -327,7 +337,8 @@
return result_per_shrinker
def BuildAppWithShrinker(
- app, config, shrinker, checkout_dir, out_dir, options, env_vars=None):
+ app, config, shrinker, checkout_dir, out_dir, temp_dir, options,
+ env_vars=None):
print()
print('Building {} with {}'.format(app, shrinker))
@@ -335,7 +346,7 @@
if options.disable_tot:
as_utils.remove_r8_dependency(checkout_dir)
else:
- as_utils.add_r8_dependency(checkout_dir, IsMinifiedR8(shrinker))
+ as_utils.add_r8_dependency(checkout_dir, temp_dir, IsMinifiedR8(shrinker))
app_module = config.get('app_module', 'app')
archives_base_name = config.get('archives_base_name', app_module)
@@ -419,7 +430,7 @@
apk_dest = os.path.join(out_dir, unsigned_apk_name)
as_utils.MoveFile(unsigned_apk, apk_dest)
- assert IsBuiltWithR8(apk_dest) == ('r8' in shrinker), (
+ assert IsBuiltWithR8(apk_dest, temp_dir) == ('r8' in shrinker), (
'Unexpected marker in generated APK for {}'.format(shrinker))
profile_dest_dir = os.path.join(out_dir, 'profile')
@@ -428,13 +439,15 @@
return (apk_dest, profile_dest_dir, proguard_config_dest)
def RebuildAppWithShrinker(
- apk, apk_dest, proguard_config_file, shrinker, min_sdk, compile_sdk):
+ apk, apk_dest, proguard_config_file, shrinker, min_sdk, compile_sdk,
+ temp_dir):
assert 'r8' in shrinker
assert apk_dest.endswith('.apk')
# Compile given APK with shrinker to temporary zip file.
android_jar = utils.get_android_jar(compile_sdk)
- r8_jar = utils.R8LIB_JAR if IsMinifiedR8(shrinker) else utils.R8_JAR
+ r8_jar = os.path.join(
+ temp_dir, 'r8lib.jar' if IsMinifiedR8(shrinker) else 'r8.jar')
zip_dest = apk_dest[:-4] + '.zip'
# TODO(christofferqa): Entry point should be CompatProguard if the shrinker
@@ -613,32 +626,39 @@
global SHRINKERS
(options, args) = ParseOptions(argv)
- assert options.disable_tot or os.path.isfile(utils.R8_JAR), (
- 'Cannot build from ToT without r8.jar')
- assert options.disable_tot or os.path.isfile(utils.R8LIB_JAR), (
- 'Cannot build from ToT without r8lib.jar')
- if options.disable_tot:
- # Cannot run r8 lib without adding r8lib.jar as an dependency
- SHRINKERS = [
- shrinker for shrinker in SHRINKERS
- if 'minified' not in shrinker]
+ with utils.TempDir() as temp_dir:
+ if options.disable_tot:
+ # Cannot run r8 lib without adding r8lib.jar as an dependency
+ SHRINKERS = [
+ shrinker for shrinker in SHRINKERS
+ if 'minified' not in shrinker]
+ else:
+ if not options.no_build:
+ gradle.RunGradle(['r8', 'r8lib'])
- if not options.no_build and not options.disable_tot:
- gradle.RunGradle(['r8', 'r8lib'])
+ assert os.path.isfile(utils.R8_JAR), (
+ 'Cannot build from ToT without r8.jar')
+ assert os.path.isfile(utils.R8LIB_JAR), (
+ 'Cannot build from ToT without r8lib.jar')
- result_per_shrinker_per_app = {}
+ # Make a copy of r8.jar and r8lib.jar such that they stay the same for
+ # the entire execution of this script.
+ shutil.copyfile(utils.R8_JAR, os.path.join(temp_dir, 'r8.jar'))
+ shutil.copyfile(utils.R8LIB_JAR, os.path.join(temp_dir, 'r8lib.jar'))
- if options.app:
- result_per_shrinker_per_app[options.app] = GetResultsForApp(
- options.app, APPS.get(options.app), options)
- else:
- for app, config in APPS.iteritems():
- if not config.get('skip', False):
- result_per_shrinker_per_app[app] = GetResultsForApp(
- app, config, options)
+ result_per_shrinker_per_app = {}
- LogResultsForApps(result_per_shrinker_per_app, options)
+ if options.app:
+ result_per_shrinker_per_app[options.app] = GetResultsForApp(
+ options.app, APPS.get(options.app), options, temp_dir)
+ else:
+ for app, config in APPS.iteritems():
+ if not config.get('skip', False):
+ result_per_shrinker_per_app[app] = GetResultsForApp(
+ app, config, options, temp_dir)
+
+ LogResultsForApps(result_per_shrinker_per_app, options)
def success(message):
CGREEN = '\033[32m'