blob: e21dc7d22d8ef5d93a27c3c99f5a242d10d6cd49 [file] [log] [blame] [edit]
#!/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',
'9.0.0',
'8.1.0',
'7.0.0',
'6.0.1',
'5.1.1',
]
DIRS = {
'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 = {
'default': 'angler',
'9.0.0': 'marlin',
'8.1.0': 'marlin',
'7.0.0': 'angler',
'6.0.1': 'angler',
'5.1.1': 'mako',
}
ARCHS = {
'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',
]
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)
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 is not 'all']
for version in versions:
run(dexfile, oatfile, version, verbose)
print
return 0
def run(dexfile, oatfile=None, version='default', verbose=[]):
# 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]
env = {"LD_LIBRARY_PATH": os.path.join(base, 'lib')}
utils.PrintCmd(cmd)
subprocess.check_call(cmd, env = env)
if __name__ == '__main__':
sys.exit(Main())