blob: 10c4732674526ef28dddd2618b39820785663ba7 [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('--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.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]
verbose = [options.verbose] if options.verbose else []
if 'all' in verbose:
verbose = [x for x in VERBOSE_OPTIONS if x != 'all']
for version in versions:
run(dexfile, oatfile, version, verbose)
print("")
return 0
def run(dexfile, oatfile=None, version=None, verbose=[]):
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,
]
for flag in verbose:
cmd += ['--runtime-arg', '-verbose:' + flag]
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())