blob: 58b2418af14de21e2e48184bbcd758021aaad4cc [file] [log] [blame]
#!/usr/bin/env python3
# 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')
LATEST = '12.0.0'
VERSIONS = [
'12.0.0',
# TODO(b/258170524): Fix the broken dex2oat versions.
# 'default',
# '9.0.0',
# '8.1.0',
# '7.0.0',
'6.0.1',
# '5.1.1',
]
DIRS = {
'12.0.0': 'host/art-12.0.0-beta4',
'default': 'art',
'9.0.0': 'art-9.0.0',
'8.1.0': 'art-8.1.0',
'7.0.0': 'art-7.0.0',
'6.0.1': 'art-6.0.1',
'5.1.1': 'art-5.1.1',
}
PRODUCTS = {
'12.0.0': 'redfin',
'default': 'angler',
'9.0.0': 'marlin',
'8.1.0': 'marlin',
'7.0.0': 'angler',
'6.0.1': 'angler',
'5.1.1': 'mako',
}
ARCHS = {
'12.0.0': 'x86_64',
'default': 'arm64',
'9.0.0': 'arm64',
'8.1.0': 'arm64',
'7.0.0': 'arm64',
'6.0.1': 'arm64',
'5.1.1': 'arm',
}
VERBOSE_OPTIONS = [
'verifier',
'compiler',
'gc',
'jit',
'jni',
'class',
'all',
]
BOOT_IMAGE = {'12.0.0': 'apex/art_boot_images/javalib/boot.art'}
def ParseOptions():
parser = optparse.OptionParser()
parser.add_option('--version',
help='Version of dex2oat. (defaults to latest: ' +
LATEST + ').',
choices=VERSIONS,
default=LATEST)
parser.add_option(
'--device',
help='Run dex2oat on this device (this is passed as the -s SERIAL.')
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)
parser.add_option('--verbose',
help='Enable verbose dex2oat logging.',
choices=VERBOSE_OPTIONS,
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.device):
return run_device_dex2oat(options, args)
else:
return run_host_dex2oat(options, args)
def run_host_dex2oat(options, args):
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(options, dexfile, oatfile, version)
print("")
return 0
def adb_cmd(serial, *args):
cmd = ['adb', '-s', serial]
cmd.extend(args)
return cmd
def append_dex2oat_verbose_flags(options, cmd):
verbose = [options.verbose] if options.verbose else []
if 'all' in verbose:
verbose = [x for x in VERBOSE_OPTIONS if x != 'all']
for flag in verbose:
cmd += ['--runtime-arg', '-verbose:' + flag]
return cmd
def run_device_dex2oat(options, args):
serial = options.device
dexfile = args[0]
device_dexfile = '/data/local/tmp/' + os.path.basename(dexfile)
device_oatfile = '/data/local/tmp/unused.oat'
cmd = adb_cmd(serial, 'shell', 'rm', '-f', device_dexfile, device_oatfile)
utils.PrintCmd(cmd)
subprocess.check_call(cmd)
cmd = adb_cmd(serial, 'push', dexfile, device_dexfile)
utils.PrintCmd(cmd)
subprocess.check_call(cmd)
cmd = adb_cmd(serial, 'logcat', '-c')
utils.PrintCmd(cmd)
subprocess.check_call(cmd)
cmd = adb_cmd(serial, 'shell', 'dex2oat', '--dex-file=' + device_dexfile,
'--oat-file=/data/local/tmp/unused.oat')
append_dex2oat_verbose_flags(options, cmd)
utils.PrintCmd(cmd)
subprocess.check_call(cmd)
cmd = adb_cmd(serial, 'logcat', '-d', '-s', 'dex2oat', 'dex2oat_original')
utils.PrintCmd(cmd)
subprocess.check_call(cmd)
return 0
def run(options, dexfile, oatfile=None, version=None):
if not version:
version = LATEST
# 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]
arch = ARCHS[version]
cmd = [
os.path.join(base, 'bin', 'dex2oat'),
'--android-root=' +
os.path.join(base, 'product', product, 'system'),
'--runtime-arg',
'-Xnorelocate',
'--dex-file=' + dexfile,
'--oat-file=' + oatfile,
'--instruction-set=' + arch,
]
append_dex2oat_verbose_flags(options, cmd)
if version in BOOT_IMAGE:
cmd += ['--boot-image=' + BOOT_IMAGE[version]]
env = {"LD_LIBRARY_PATH": os.path.join(base, 'lib')}
utils.PrintCmd(cmd)
with utils.ChangedWorkingDirectory(base):
subprocess.check_call(cmd, env=env)
if __name__ == '__main__':
sys.exit(Main())