#!/usr/bin/env python3
# Copyright (c) 2017, 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.

from __future__ import print_function
from glob import glob
import copy
import optparse
import os
import shutil
import sys
import time

import archive
import as_utils
import gmail_data
import gmscore_data
import golem
import nest_data
from sanitize_libraries import SanitizeLibraries, SanitizeLibrariesInPgconf
import toolhelper
import update_prebuilds_in_android
import utils
import youtube_data
import chrome_data
import r8_data
import iosched_data

TYPES = ['dex', 'deploy', 'proguarded']
APPS = [
  'gmscore', 'nest', 'youtube', 'gmail', 'chrome', 'r8', 'iosched']
COMPILERS = ['d8', 'r8']
COMPILER_BUILDS = ['full', 'lib']

# We use this magic exit code to signal that the program OOM'ed
OOM_EXIT_CODE = 42
# According to Popen.returncode doc:
# A negative value -N indicates that the child was terminated by signal N.
TIMEOUT_KILL_CODE = -9

# Log file names
FIND_MIN_XMX_FILE = 'find_min_xmx_results'
FIND_MIN_XMX_DIR = 'find_min_xmx'

def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option('--compiler',
                    help='The compiler to use',
                    choices=COMPILERS)
  result.add_option('--compiler-build',
                    help='Compiler build to use',
                    choices=COMPILER_BUILDS,
                    default='lib')
  result.add_option('--hash',
                    help='The version of D8/R8 to use')
  result.add_option('--app',
                    help='What app to run on',
                    choices=APPS)
  result.add_option('--run-all',
                    help='Compile all possible combinations',
                    default=False,
                    action='store_true')
  result.add_option('--expect-oom',
                    help='Expect that compilation will fail with an OOM',
                    default=False,
                    action='store_true')
  result.add_option('--type',
                    help='Default for R8: deploy, for D8: proguarded',
                    choices=TYPES)
  result.add_option('--out',
                    help='Where to place the output',
                    default=utils.BUILD)
  result.add_option('--no-build',
                    help='Run without building first',
                    default=False,
                    action='store_true')
  result.add_option('--max-memory',
                    help='The maximum memory in MB to run with',
                    type='int')
  result.add_option('--find-min-xmx',
                    help='Find the minimum amount of memory we can run in',
                    default=False,
                    action='store_true')
  result.add_option('--find-min-xmx-min-memory',
                    help='Setting the minimum memory baseline to run in',
                    type='int')
  result.add_option('--find-min-xmx-max-memory',
                    help='Setting the maximum memory baseline to run in',
                    type='int')
  result.add_option('--find-min-xmx-range-size',
                    help='Setting the size of the acceptable memory range',
                    type='int',
                    default=32)
  result.add_option('--find-min-xmx-archive',
                    help='Archive find-min-xmx results on GCS',
                    default=False,
                    action='store_true')
  result.add_option('--no-extra-pgconf', '--no_extra_pgconf',
                    help='Build without the following extra rules: ' +
                         '-printconfiguration, -printmapping, -printseeds, ' +
                         '-printusage',
                    default=False,
                    action='store_true')
  result.add_option('--timeout',
                    type='int',
                    default=0,
                    help='Set timeout instead of waiting for OOM.')
  result.add_option('--golem',
                    help='Running on golem, do not build or download',
                    default=False,
                    action='store_true')
  result.add_option('--ignore-java-version',
                    help='Do not check java version',
                    default=False,
                    action='store_true')
  result.add_option('--no-libraries',
                    help='Do not pass in libraries, even if they exist in conf',
                    default=False,
                    action='store_true')
  result.add_option('--no-debug',
                    help='Run without debug asserts.',
                    default=False,
                    action='store_true')
  result.add_option('--debug-agent',
                    help='Run with debug agent.',
                    default=False,
                    action='store_true')
  result.add_option('--version',
                    help='The version of the app to run')
  result.add_option('-k',
                    help='Override the default ProGuard keep rules')
  result.add_option('--compiler-flags',
                    help='Additional option(s) for the compiler. ' +
                         'If passing several options use a quoted string.')
  result.add_option('--r8-flags',
                    help='Additional option(s) for the compiler. ' +
                         'Same as --compiler-flags, keeping it for backward'
                         ' compatibility. ' +
                         'If passing several options use a quoted string.')
  # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
  # to use --print-memoryuse instead
  result.add_option('--track-memory-to-file',
                    help='Track how much memory the jvm is using while ' +
                    ' compiling. Output to the specified file.')
  result.add_option('--profile',
                    help='Profile R8 run.',
                    default=False,
                    action='store_true')
  result.add_option('--dump-args-file',
                    help='Dump a file with the arguments for the specified ' +
                    'configuration. For use as a @<file> argument to perform ' +
                    'the run.')
  result.add_option('--print-runtimeraw',
                    metavar='BENCHMARKNAME',
                    help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
                        ' <elapsed> ms\' at the end where <elapsed> is' +
                        ' the elapsed time in milliseconds.')
  result.add_option('--print-memoryuse',
                    metavar='BENCHMARKNAME',
                    help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
                        ' <mem>\' at the end where <mem> is the peak' +
                        ' peak resident set size (VmHWM) in bytes.')
  result.add_option('--print-dexsegments',
                    metavar='BENCHMARKNAME',
                    help='Print the sizes of individual dex segments as ' +
                        '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
  result.add_option('--track-time-in-memory',
                    help='Plot the times taken from memory starting point to '
                         'end-point with defined memory increment',
                    default=False,
                    action='store_true')
  result.add_option('--track-time-in-memory-max',
                    help='Setting the maximum memory baseline to run in',
                    type='int')
  result.add_option('--track-time-in-memory-min',
                    help='Setting the minimum memory baseline to run in',
                    type='int')
  result.add_option('--track-time-in-memory-increment',
                    help='Setting the increment',
                    type='int',
                    default=32)
  result.add_option('--print-times',
                    help='Include timing',
                    default=False,
                    action='store_true')
  result.add_option('--cpu-list',
                    help='Run under \'taskset\' with these CPUs. See '
                         'the \'taskset\' -c option for the format')
  result.add_option('--quiet',
                    help='Disable compiler logging',
                    default=False,
                    action='store_true')
  (options, args) = result.parse_args(argv)
  assert not options.hash or options.no_build, (
      'Argument --no-build is required when using --hash')
  assert not options.hash or options.compiler_build == 'full', (
      'Compiler build lib not yet supported with --hash')
  return (options, args)

# Most apps have -printmapping, -printseeds, -printusage and
# -printconfiguration in the Proguard configuration. However we don't
# want to write these files in the locations specified.
# Instead generate an auxiliary Proguard configuration placing these
# output files together with the dex output.
def GenerateAdditionalProguardConfiguration(temp, outdir):
  name = "output.config"
  with open(os.path.join(temp, name), 'w') as f:
    f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
    f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
    f.write('-printusage ' + os.path.join(outdir, 'proguard.usage') + "\n")
    f.write('-printconfiguration ' + os.path.join(outdir, 'proguard.config') + "\n")
    return os.path.abspath(f.name)

# Please add bug number for disabled permutations and please explicitly
# do Bug: #BUG in the commit message of disabling to ensure re-enabling
DISABLED_PERMUTATIONS = [
  # (app, version, type), e.g., ('gmail', '180826.15', 'deploy')
]

def get_permutations():
  data_providers = {
      'gmscore': gmscore_data,
      'nest': nest_data,
      'youtube': youtube_data,
      'chrome': chrome_data,
      'gmail': gmail_data,
      'r8': r8_data,
      'iosched': iosched_data,
  }
  # Check to ensure that we add all variants here.
  assert len(APPS) == len(data_providers)
  for app, data in data_providers.items():
    for version in data.VERSIONS:
      for type in data.VERSIONS[version]:
        if (app, version, type) not in DISABLED_PERMUTATIONS:
          for use_r8lib in [False, True]:
            yield app, version, type, use_r8lib

def run_all(options, args):
  # Args will be destroyed
  assert len(args) == 0
  for name, version, type, use_r8lib in get_permutations():
    compiler = 'r8' if type == 'deploy' else 'd8'
    compiler_build = 'lib' if use_r8lib else 'full'
    print('Executing %s/%s with %s %s %s' % (compiler, compiler_build, name,
      version, type))

    fixed_options = copy.copy(options)
    fixed_options.app = name
    fixed_options.version = version
    fixed_options.compiler = compiler
    fixed_options.compiler_build = compiler_build
    fixed_options.type = type
    exit_code = run_with_options(fixed_options, [])
    if exit_code != 0:
      print('Failed %s %s %s with %s/%s' % (name, version, type, compiler,
        compiler_build))
      exit(exit_code)

def find_min_xmx(options, args):
  # Args will be destroyed
  assert len(args) == 0
  # If we can run in 128 MB then we are good (which we can for small examples
  # or D8 on medium sized examples)
  if options.find_min_xmx_min_memory:
    not_working = options.find_min_xmx_min_memory
  elif options.compiler == 'd8':
    not_working = 128
  else:
    not_working = 1024
  if options.find_min_xmx_max_memory:
    working = options.find_min_xmx_max_memory
  else:
    working = 1024 * 8
  exit_code = 0
  range = int(options.find_min_xmx_range_size)
  while working - not_working > range:
    next_candidate = int(working - ((working - not_working)/2))
    print('working: %s, non_working: %s, next_candidate: %s' %
          (working, not_working, next_candidate))
    extra_args = ['-Xmx%sM' % next_candidate]
    t0 = time.time()
    exit_code = run_with_options(options, [], extra_args)
    t1 = time.time()
    print('Running took: %s ms' % (1000.0 * (t1 - t0)))
    if exit_code != 0:
      if exit_code not in [OOM_EXIT_CODE, TIMEOUT_KILL_CODE]:
        print('Non OOM/Timeout error executing, exiting')
        return 2
    if exit_code == 0:
      working = next_candidate
    elif exit_code == TIMEOUT_KILL_CODE:
      print('Timeout. Continue to the next candidate.')
      not_working = next_candidate
    else:
      assert exit_code == OOM_EXIT_CODE
      not_working = next_candidate

  assert working - not_working <= range
  found_range = 'Found range: %s - %s' % (not_working, working)
  print(found_range)

  if options.find_min_xmx_archive:
    sha = utils.get_HEAD_sha1()
    (version, _) = get_version_and_data(options)
    destination = os.path.join(
        utils.R8_TEST_RESULTS_BUCKET,
        FIND_MIN_XMX_DIR,
        sha,
        options.compiler,
        options.compiler_build,
        options.app,
        version,
        get_type(options))
    gs_destination = 'gs://%s' % destination
    utils.archive_value(FIND_MIN_XMX_FILE, gs_destination, found_range + '\n')

  return 0

def print_min_xmx_ranges_for_hash(hash, compiler, compiler_build):
  app_directory = os.path.join(
      utils.R8_TEST_RESULTS_BUCKET,
      FIND_MIN_XMX_DIR,
      hash,
      compiler,
      compiler_build)
  gs_base = 'gs://%s' % app_directory
  for app in utils.ls_files_on_cloud_storage(gs_base).strip().split('\n'):
    for version in utils.ls_files_on_cloud_storage(app).strip().split('\n'):
      for type in utils.ls_files_on_cloud_storage(version).strip().split('\n'):
        gs_location = '%s%s' % (type, FIND_MIN_XMX_FILE)
        value = utils.cat_file_on_cloud_storage(gs_location, ignore_errors=True)
        print('%s\n' % value)

def track_time_in_memory(options, args):
  # Args will be destroyed
  assert len(args) == 0
  if not options.track_time_in_memory_min:
    raise Exception(
        'You have to specify --track_time_in_memory_min when running with '
        '--track-time-in-memory')
  if not options.track_time_in_memory_max:
    raise Exception(
        'You have to specify --track_time_in_memory_max when running with '
        '--track-time-in-memory')
  if not options.track_time_in_memory_increment:
    raise Exception(
        'You have to specify --track_time_in_memory_increment when running '
        'with --track-time-in-memory')
  current = options.track_time_in_memory_min
  print('Memory (KB)\tTime (ms)')
  with utils.TempDir() as temp:
    stdout = os.path.join(temp, 'stdout')
    stdout_fd = open(stdout, 'w')
    while current <= options.track_time_in_memory_max:
      extra_args = ['-Xmx%sM' % current]
      t0 = time.time()
      exit_code = run_with_options(options, [], extra_args, stdout_fd, quiet=True)
      t1 = time.time()
      total = (1000.0 * (t1 - t0)) if exit_code == 0 else -1
      print('%s\t%s' % (current, total))
      current += options.track_time_in_memory_increment

  return 0

def main(argv):
  (options, args) = ParseOptions(argv)
  if options.expect_oom and not options.max_memory:
    raise Exception(
        'You should only use --expect-oom if also specifying --max-memory')
  if options.expect_oom and options.timeout:
    raise Exception(
        'You should not use --timeout when also specifying --expect-oom')
  if options.find_min_xmx and options.track_time_in_memory:
    raise Exception(
        'You cannot both find the min xmx and track time at the same time')
  if options.run_all:
    return run_all(options, args)
  if options.find_min_xmx:
    return find_min_xmx(options, args)
  if options.track_time_in_memory:
    return track_time_in_memory(options, args)
  exit_code = run_with_options(options, args, quiet=options.quiet)
  if options.expect_oom:
    exit_code = 0 if exit_code == OOM_EXIT_CODE else 1
  return exit_code

def get_version_and_data(options):
  if options.app == 'gmscore':
    version = options.version or gmscore_data.LATEST_VERSION
    data = gmscore_data
  elif options.app == 'nest':
    version = options.version or '20180926'
    data = nest_data
  elif options.app == 'youtube':
    version = options.version or youtube_data.LATEST_VERSION
    data = youtube_data
  elif options.app == 'chrome':
    version = options.version or '180917'
    data = chrome_data
  elif options.app == 'gmail':
    version = options.version or '170604.16'
    data = gmail_data
  elif options.app == 'r8':
    version = options.version or 'cf'
    data = r8_data
  elif options.app == 'iosched':
    version = options.version or '2019'
    data = iosched_data
  else:
    raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))
  return version, data

def get_type(options):
  if not options.type:
    return 'deploy' if options.compiler == 'r8' else 'proguarded'
  return options.type

def has_injars_and_libraryjars(pgconfs):
  # Check if there are -injars and -libraryjars in the configuration.
  has_injars = False
  has_libraryjars = False
  for pgconf in pgconfs:
    pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
    with open(pgconf) as pgconf_file:
      for line in pgconf_file:
        trimmed = line.strip()
        if trimmed.startswith('-injars'):
          has_injars = True
        elif trimmed.startswith('-libraryjars'):
          has_libraryjars = True
        if has_injars and has_libraryjars:
          return True
  return False

def check_no_injars_and_no_libraryjars(pgconfs):
  # Ensure that there are no -injars or -libraryjars in the configuration.
  for pgconf in pgconfs:
    pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
    with open(pgconf) as pgconf_file:
      for line in pgconf_file:
        trimmed = line.strip()
        if trimmed.startswith('-injars'):
          raise Exception("Unexpected -injars found in " + pgconf)
        elif trimmed.startswith('-libraryjars'):
          raise Exception("Unexpected -libraryjars found in " + pgconf)

def should_build(options):
  return not options.no_build and not options.golem

def build_desugared_library_dex(
    options,
    quiet,
    temp,
    android_java8_libs,
    desugared_lib_pg_conf,
    inputs,
    outdir):
  if not inputs:
    raise Exception(
        "If 'android_java8_libs' is specified the inputs must be explicit"
            + "(not defined using '-injars' in Proguard configuration files)")
  if outdir.endswith('.zip') or outdir.endswith('.jar'):
    raise Exception(
        "If 'android_java8_libs' is specified the output must be a directory")

  jar = None
  main = None
  if options.hash:
    jar = os.path.join(utils.LIBS, 'r8-' + options.hash + '.jar')
    main = 'com.android.tools.r8.R8'

  # Determine the l8 tool.
  assert(options.compiler_build in ['full', 'lib'])
  lib_prefix = 'r8lib-' if options.compiler_build == 'lib' else ''
  tool = lib_prefix + 'l8'

  # Prepare out directory.
  android_java8_libs_output = os.path.join(temp, 'android_java8_libs')
  os.makedirs(android_java8_libs_output)

  # Prepare arguments for L8.
  args = [
    '--desugared-lib', android_java8_libs['config'],
    '--lib', android_java8_libs['library'],
    '--output', android_java8_libs_output,
    '--pg-conf', desugared_lib_pg_conf,
    '--release',
  ]
  if 'pgconf' in android_java8_libs:
    for pgconf in android_java8_libs['pgconf']:
      args.extend(['--pg-conf', pgconf])
  args.extend(android_java8_libs['program'])

  # Run L8.
  exit_code = toolhelper.run(
      tool, args,
      build=should_build(options),
      debug=not options.no_debug,
      quiet=quiet,
      jar=jar,
      main=main)

  # Copy the desugared library DEX to the output.
  dex_file_name = (
      'classes' + str(len(glob(os.path.join(outdir, '*.dex'))) + 1) + '.dex')
  shutil.copyfile(
      os.path.join(android_java8_libs_output, 'classes.dex'),
      os.path.join(outdir, dex_file_name))

def run_with_options(options, args, extra_args=None, stdout=None, quiet=False):
  if extra_args is None:
    extra_args = []
  app_provided_pg_conf = False;
  # todo(121018500): remove when memory is under control
  if not any('-Xmx' in arg for arg in extra_args):
    if options.max_memory:
      extra_args.append('-Xmx%sM' % options.max_memory)
    else:
      extra_args.append('-Xmx8G')
  if options.golem:
    golem.link_third_party()
    options.out = os.getcwd()
  if not options.ignore_java_version:
    utils.check_java_version()

  if options.print_times:
    extra_args.append('-Dcom.android.tools.r8.printtimes=1')

  if not options.no_debug:
    extra_args.append('-Dcom.android.tools.r8.enableTestAssertions=1')

  outdir = options.out
  (version_id, data) = get_version_and_data(options)

  if options.compiler not in COMPILERS:
    raise Exception("You need to specify '--compiler={}'"
        .format('|'.join(COMPILERS)))

  if options.compiler_build not in COMPILER_BUILDS:
    raise Exception("You need to specify '--compiler-build={}'"
        .format('|'.join(COMPILER_BUILDS)))

  if not version_id in data.VERSIONS.keys():
    print('No version {} for application {}'
        .format(version_id, options.app))
    print('Valid versions are {}'.format(data.VERSIONS.keys()))
    return 1

  version = data.VERSIONS[version_id]

  type = get_type(options)

  if type not in version:
    print('No type {} for version {}'.format(type, version))
    print('Valid types are {}'.format(version.keys()))
    return 1
  values = version[type]

  args.extend(['--output', outdir])
  if 'min-api' in values:
    args.extend(['--min-api', values['min-api']])

  if 'main-dex-list' in values:
    args.extend(['--main-dex-list', values['main-dex-list']])

  inputs = values['inputs']
  libraries = values['libraries'] if 'libraries' in values else []

  if options.compiler == 'r8':
    if 'pgconf' in values and not options.k:
      if has_injars_and_libraryjars(values['pgconf']):
        sanitized_lib_path = os.path.join(
            os.path.abspath(outdir), 'sanitized_lib.jar')
        sanitized_pgconf_path = os.path.join(
            os.path.abspath(outdir), 'sanitized.config')
        SanitizeLibrariesInPgconf(
            sanitized_lib_path, sanitized_pgconf_path, values['pgconf'])
        libraries = [sanitized_lib_path]
        args.extend(['--pg-conf', sanitized_pgconf_path])
        inputs = []
      else:
        # -injars without -libraryjars or vice versa is not supported.
        check_no_injars_and_no_libraryjars(values['pgconf'])
        for pgconf in values['pgconf']:
          args.extend(['--pg-conf', pgconf])
        if 'sanitize_libraries' in values and values['sanitize_libraries']:
          sanitized_lib_path = os.path.join(
              os.path.abspath(outdir), 'sanitized_lib.jar')
          SanitizeLibraries(
            sanitized_lib_path, values['libraries'], values['inputs'])
          libraries = [sanitized_lib_path]
      app_provided_pg_conf = True
      if 'pgconf_extra' in values:
        extra_conf = os.path.join(os.path.abspath(outdir), 'pgconf_extra')
        with open(extra_conf, 'w') as extra_f:
          extra_f.write(values['pgconf_extra'])
        args.extend(['--pg-conf', extra_conf])
    if options.k:
      args.extend(['--pg-conf', options.k])
    if 'maindexrules' in values:
      for rules in values['maindexrules']:
        args.extend(['--main-dex-rules', rules])
    if 'allow-type-errors' in values:
      extra_args.append('-Dcom.android.tools.r8.allowTypeErrors=1')
    extra_args.append(
        '-Dcom.android.tools.r8.disallowClassInlinerGracefulExit=1')

  if options.debug_agent:
    if not options.compiler_build == 'full':
      print('WARNING: Running debugging agent on r8lib is questionable...')
    extra_args.append(
      '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005')

  if not options.no_libraries:
    for lib in libraries:
      args.extend(['--lib', lib])

  if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
      and not os.path.exists(outdir):
    os.makedirs(outdir)

  if options.hash:
    # Download r8-<hash>.jar from
    # https://storage.googleapis.com/r8-releases/raw/<hash>/.
    download_path = archive.GetUploadDestination(options.hash, 'r8.jar', True)
    assert utils.file_exists_on_cloud_storage(download_path), (
        'Could not find r8.jar file from provided hash: %s' % options.hash)
    destination = os.path.join(utils.LIBS, 'r8-' + options.hash + '.jar')
    utils.download_file_from_cloud_storage(
        download_path, destination, quiet=quiet)

  # Additional flags for the compiler from the configuration file.
  if 'flags' in values:
    args.extend(values['flags'].split(' '))
  if options.compiler == 'r8':
    if 'r8-flags' in values:
      args.extend(values['r8-flags'].split(' '))

  # Additional flags for the compiler from the command line.
  if options.compiler_flags:
    args.extend(options.compiler_flags.split(' '))
  if options.r8_flags:
    args.extend(options.r8_flags.split(' '))

  # Feature jars.
  features = values['features'] if 'features' in values else []
  for i, feature in enumerate(features, start=1):
    feature_out = os.path.join(outdir, 'feature-%d.zip' % i)
    for feature_jar in feature['inputs']:
      args.extend(['--feature', feature_jar, feature_out])

  args.extend(inputs)

  t0 = time.time()
  if options.dump_args_file:
    with open(options.dump_args_file, 'w') as args_file:
      args_file.writelines([arg + os.linesep for arg in args])
  else:
    with utils.TempDir() as temp:
      if options.print_memoryuse and not options.track_memory_to_file:
        options.track_memory_to_file = os.path.join(temp,
            utils.MEMORY_USE_TMP_FILE)
      if options.compiler == 'r8' and app_provided_pg_conf:
        # Ensure that output of -printmapping and -printseeds go to the output
        # location and not where the app Proguard configuration places them.
        if outdir.endswith('.zip') or outdir.endswith('.jar'):
          pg_outdir = os.path.dirname(outdir)
        else:
          pg_outdir = outdir
        if not options.no_extra_pgconf:
          additional_pg_conf = GenerateAdditionalProguardConfiguration(
              temp, os.path.abspath(pg_outdir))
          args.extend(['--pg-conf', additional_pg_conf])

      android_java8_libs = values.get('android_java8_libs')
      if android_java8_libs:
        desugared_lib_pg_conf = os.path.join(
            temp, 'desugared-lib-pg-conf.txt')
        args.extend(['--desugared-lib', android_java8_libs['config']])
        args.extend(
            ['--desugared-lib-pg-conf-output', desugared_lib_pg_conf])

      stderr_path = os.path.join(temp, 'stderr')
      with open(stderr_path, 'w') as stderr:
        jar = None
        main = None
        if options.compiler_build == 'full':
          tool = options.compiler
        else:
          assert(options.compiler_build == 'lib')
          tool = 'r8lib-' + options.compiler
        if options.hash:
          jar = os.path.join(utils.LIBS, 'r8-' + options.hash + '.jar')
          main = 'com.android.tools.r8.' + options.compiler.upper()
        exit_code = toolhelper.run(tool, args,
            build=should_build(options),
            debug=not options.no_debug,
            profile=options.profile,
            track_memory_file=options.track_memory_to_file,
            extra_args=extra_args,
            stdout=stdout,
            stderr=stderr,
            timeout=options.timeout,
            quiet=quiet,
            cmd_prefix=[
                'taskset', '-c', options.cpu_list] if options.cpu_list else [],
            jar=jar,
            main=main)
      if exit_code != 0:
        with open(stderr_path) as stderr:
          stderr_text = stderr.read()
          if not quiet:
            print(stderr_text)
          if 'java.lang.OutOfMemoryError' in stderr_text:
            if not quiet:
              print('Failure was OOM')
            return OOM_EXIT_CODE
          return exit_code

      if options.print_memoryuse:
        print('{}(MemoryUse): {}'
            .format(options.print_memoryuse,
                utils.grep_memoryuse(options.track_memory_to_file)))

      if android_java8_libs:
        build_desugared_library_dex(
            options, quiet, temp, android_java8_libs,
            desugared_lib_pg_conf, inputs, outdir)


  if options.print_runtimeraw:
    print('{}(RunTimeRaw): {} ms'
        .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))

  if options.print_dexsegments:
    dex_files = glob(os.path.join(outdir, '*.dex'))
    utils.print_dexsegments(options.print_dexsegments, dex_files)
  return 0

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
