#!/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 gradle
import gmail_data
import nest_data
from sanitize_libraries import SanitizeLibraries, SanitizeLibrariesInPgconf
import thread_utils
from thread_utils import print_thread
import toolhelper
import update_prebuilds_in_android
import utils
import youtube_data
import chrome_data

TYPES = ['dex', 'deploy', 'proguarded']
APPS = ['nest', 'youtube', 'gmail', 'chrome']
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('--no-fail-fast',
                    help='Whether run_on_app.py should report all failures '
                         'and not just the first one',
                    default=False,
                    action='store_true')
  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('--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.')
  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')
  result.add_option('--workers',
                    help='Number of workers to use',
                    default=1,
                    type=int)
  (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 = {
      'nest': nest_data,
      'youtube': youtube_data,
      'chrome': chrome_data,
      'gmail': gmail_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:
          # Only run with R8 lib to reduce cycle times.
          for use_r8lib in [True]:
            yield app, version, type, use_r8lib

def run_all(options, args):
  # Build first so that each job won't.
  if should_build(options):
    gradle.RunGradle(['r8lib'])
    options.no_build = True
  assert not should_build(options)

  # Args will be destroyed
  assert len(args) == 0
  jobs = []
  for name, version, type, use_r8lib in get_permutations():
    compiler = 'r8' if type == 'deploy' else 'd8'
    compiler_build = 'lib' if use_r8lib else 'full'
    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
    jobs.append(
        create_job(
            compiler, compiler_build, name, fixed_options, type, version))
  exit_code = thread_utils.run_in_parallel(
      jobs,
      number_of_workers=options.workers,
      stop_on_first_failure=not options.no_fail_fast)
  exit(exit_code)

def create_job(compiler, compiler_build, name, options, type, version):
  return lambda worker_id: run_job(
      compiler, compiler_build, name, options, type, version, worker_id)

def run_job(
    compiler, compiler_build, name, options, type, version, worker_id):
  print_thread(
      'Executing %s/%s with %s %s %s'
          % (compiler, compiler_build, name, version, type),
      worker_id)
  if worker_id is not None:
    options.out = os.path.join(options.out, str(worker_id))
    os.makedirs(options.out, exist_ok=True)
  exit_code = run_with_options(options, [], worker_id=worker_id)
  if exit_code:
    print_thread(
        'Failed %s %s %s with %s/%s'
            % (name, version, type, compiler, compiler_build),
        worker_id)
  return 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 == '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
  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

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, worker_id=None):
  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 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:
      sanitized_lib_path = os.path.join(
          os.path.abspath(outdir), 'sanitized_lib.jar')
      if has_injars_and_libraryjars(values['pgconf']):
        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']:
          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 'system-properties' in values:
      for system_property in values['system-properties']:
        extra_args.append(system_property)

  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 = None
  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()
        if should_build(options):
          gradle.RunGradle(['r8lib' if tool.startswith('r8lib') else 'r8'])
        t0 = time.time()
        exit_code = toolhelper.run(tool, args,
            build=False,
            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,
            worker_id=worker_id)
      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)
    print('{}-Total(CodeSize): {}'.format(
            options.print_dexsegments, compute_size_of_dex_files(dex_files)))
  return 0

def compute_size_of_dex_files(dex_files):
  dex_size = 0
  for dex_file in dex_files:
    dex_size += os.path.getsize(dex_file)
  return dex_size

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