Convert most of dex2oat script to python and add version support.
Change-Id: Ib18211b12cc83fa371f4ac3f6bec083504af9fd7
diff --git a/scripts/run-dex2oat.sh b/scripts/run-dex2oat.sh
deleted file mode 100755
index 125607e..0000000
--- a/scripts/run-dex2oat.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /bin/bash
-#
-# Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-set -e
-
-if [ -z "$R8_HOME" ]; then
- R8_HOME="$(realpath $(dirname ${BASH_SOURCE[0]})/..)"
-fi
-
-TOOLSDIR=$R8_HOME/tools/linux
-
-function usage {
- echo "Usage: $(basename $0) <dex files>"
- exit 1
-}
-
-# Process options.
-while [ $# -gt 0 ]; do
- case $1 in
- -h)
- usage
- ;;
- *)
- break
- ;;
- esac
-done
-
-if [ $# -eq 0 ]; then
- usage
-fi
-
-TMPDIR=$(mktemp -d "${TMP:-/tmp/}$(basename $0).XXXXXXXXXXXX")
-OATFILE=$TMPDIR/all.oat
-
-if [ $# -gt 1 ]; then
- JARFILE="$TMPDIR/all.jar"
- for f in "$@"; do
- IR=$(dirname "$f")
- BASE=$(basename "$f")
- EXT=$(echo "$BASE" | cut -d '.' -f 2)
- if [ "$EXT" = "dex" ]; then
- (cd "$DIR" && zip "$JARFILE" "$BASE")
- else
- echo "Warning: ignoring non-dex file argument when dex2oat'ing multiple files."
- fi
- done
-else
- JARFILE="$1"
-fi
-
-LD_LIBRARY_PATH=$TOOLSDIR/art/lib $TOOLSDIR/art/bin/dex2oat \
- --android-root=$TOOLSDIR/art/product/angler \
- --runtime-arg -Xnorelocate \
- --boot-image=$TOOLSDIR/art/product/angler/system/framework/boot.art \
- --dex-file=$JARFILE \
- --oat-file=$OATFILE \
- --instruction-set=arm64
-
-rm -rf $TMPDIR
diff --git a/tools/dex2oat.py b/tools/dex2oat.py
new file mode 100755
index 0000000..eab424f
--- /dev/null
+++ b/tools/dex2oat.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import optparse
+import os
+import subprocess
+import sys
+
+import utils
+
+LINUX_DIR = os.path.join(utils.TOOLS_DIR, 'linux')
+
+VERSIONS = [
+ 'default',
+ '7.0.0',
+ '6.0.1',
+ # TODO(b/79191363): Build a boot image for 5.1.1 dex2oat.
+ # '5.1.1',
+]
+
+DIRS = {
+ 'default': 'art',
+ '7.0.0': 'art-7.0.0',
+ '6.0.1': 'art-6.0.1',
+ '5.1.1': 'art-5.1.1',
+}
+
+PRODUCTS = {
+ 'default': 'angler',
+ '7.0.0': 'angler',
+ '6.0.1': 'angler',
+ '5.1.1': 'mako',
+}
+
+def ParseOptions():
+ parser = optparse.OptionParser()
+ parser.add_option('--version',
+ help='Version of dex2oat. (defaults to latest, eg, tools/linux/art).',
+ choices=VERSIONS,
+ default='default')
+ parser.add_option('--all',
+ help='Run dex2oat on all possible versions',
+ default=False,
+ action='store_true')
+ parser.add_option('--output',
+ help='Where to place the output oat (defaults to no output / temp file).',
+ default=None)
+ return parser.parse_args()
+
+def Main():
+ (options, args) = ParseOptions()
+ if len(args) != 1:
+ print "Can only take a single dex/zip/jar/apk file as input."
+ return 1
+ if options.all and options.output:
+ print "Can't write output when running all versions."
+ return 1
+ dexfile = args[0]
+ oatfile = options.output
+ versions = VERSIONS if options.all else [options.version]
+ for version in versions:
+ run(dexfile, oatfile, version)
+ print
+ return 0
+
+def run(dexfile, oatfile=None, version='default'):
+ # dex2oat accepts non-existent dex files, check here instead
+ if not os.path.exists(dexfile):
+ raise Exception('DEX file not found: "{}"'.format(dexfile))
+ with utils.TempDir() as temp:
+ if not oatfile:
+ oatfile = os.path.join(temp, "out.oat")
+ base = os.path.join(LINUX_DIR, DIRS[version])
+ product = PRODUCTS[version]
+ cmd = [
+ os.path.join(base, 'bin', 'dex2oat'),
+ '--android-root=' + os.path.join(base, 'product', product),
+ '--runtime-arg',
+ '-Xnorelocate',
+ '--boot-image=' + os.path.join(base, 'product', product, 'system', 'framework', 'boot.art'),
+ '--dex-file=' + dexfile,
+ '--oat-file=' + oatfile,
+ '--instruction-set=arm64',
+ ]
+ env = {"LD_LIBRARY_PATH": os.path.join(base, 'lib')}
+ utils.PrintCmd(cmd)
+ subprocess.check_call(cmd, env = env)
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/tools/test_aosp_jar.py b/tools/test_aosp_jar.py
index f3aa392..bf12045 100755
--- a/tools/test_aosp_jar.py
+++ b/tools/test_aosp_jar.py
@@ -16,6 +16,7 @@
import gradle
+import dex2oat
import utils
REPLAY_SCRIPT_DIR = join(utils.REPO_ROOT, 'third_party',
@@ -44,7 +45,7 @@
for x in os.walk(OUT_DIR)))
for dex_file in dex_files:
- utils.verify_with_dex2oat(dex_file)
+ dex2oat.run(dex_file)
if __name__ == '__main__':
diff --git a/tools/utils.py b/tools/utils.py
index a734ee5..7c5d83e 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -292,36 +292,5 @@
if m is not None:
raise Exception("Do not use google JVM for benchmarking: " + version)
-def verify_with_dex2oat(dex_file):
-
- # dex2oat accepts non-existent dex files, check here instead
- if not os.path.exists(dex_file):
- raise Exception('Dex file not found: "{}"'.format(dex_file))
-
- android_root_dir = os.path.join(TOOLS_DIR, 'linux', 'art', 'product',
- 'angler')
- boot_art = os.path.join(android_root_dir, 'system', 'framework', 'boot.art')
- dex2oat = os.path.join(TOOLS_DIR, 'linux', 'art', 'bin', 'dex2oat')
-
- with TempDir() as temp:
- oat_file = os.path.join(temp, 'all.oat')
-
- cmd = [
- dex2oat,
- '--android-root=' + android_root_dir,
- '--runtime-arg', '-Xnorelocate',
- '--boot-image=' + boot_art,
- '--dex-file=' + dex_file,
- '--oat-file=' + oat_file,
- '--instruction-set=arm64',
- '--compiler-filter=quicken'
- ]
-
- PrintCmd(cmd)
- subprocess.check_call(cmd,
- env = {"LD_LIBRARY_PATH":
- os.path.join(TOOLS_DIR, 'linux', 'art', 'lib')}
- )
-
def get_android_jar(api):
return os.path.join(REPO_ROOT, ANDROID_JAR.format(api=api))