コード例 #1
0
def Main():
    (options, args) = parse_options()
    if options.golem:
        golem.link_third_party()
    with utils.TempDir() as temp:
        dex_path = os.path.join(temp, "classes.jar")
        proguard_conf = os.path.join(temp, 'proguard.conf')
        with open(proguard_conf, 'w') as f:
            f.write(PROGUARD_CONF)
        benchmark_jar = get_jar_for_benchmark(options.benchmark)
        r8_args = [
            '--lib',
            utils.get_android_jar(26),  # Only works with api 26
            '--output',
            dex_path,
            '--pg-conf',
            proguard_conf,
            '--min-api',
            str(options.api),
            benchmark_jar
        ]
        toolhelper.run('r8', r8_args, build=not options.golem)
        if options.use_device:
            result = run_art_device(dex_path)
        else:
            result = run_art(dex_path)
        print('Kotlin_{}(RunTimeRaw): {} ms'.format(options.benchmark, result))
コード例 #2
0
ファイル: run-d8-on-gmscore.py プロジェクト: singhaditya28/r8
def main():
    (options, args) = ParseOptions()
    outdir = options.out
    version = gmscore_data.VERSIONS[options.version]
    values = version[options.type]
    inputs = values['inputs']

    args.extend(['--output', outdir])

    if not os.path.exists(outdir):
        os.makedirs(outdir)

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

    if options.d8_flags:
        args.extend(options.d8_flags.split(' '))

    args.extend(inputs)

    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:
        toolhelper.run('d8',
                       args,
                       build=not options.no_build,
                       debug=not options.no_debug,
                       profile=options.profile,
                       track_memory_file=options.track_memory_to_file)
コード例 #3
0
def main(tmpdir=None, inlining=True, run_jarsizecompare=True, threshold=None):
    if tmpdir is None:
        with utils.TempDir() as tmpdir:
            return main(tmpdir, inlining)

    inline_suffix = '-inline' if inlining else '-noinline'

    pg_config = utils.R8LIB_KEEP_RULES
    r8lib_jar = os.path.join(utils.LIBS, 'r8lib%s.jar' % inline_suffix)
    r8lib_map = os.path.join(utils.LIBS, 'r8lib%s-map.txt' % inline_suffix)
    r8lib_args = None
    if not inlining:
        r8lib_args = ['-Dcom.android.tools.r8.disableinlining=1']
        pg_config = os.path.join(tmpdir, 'keep-noinline.txt')
        with open(pg_config, 'w') as new_config:
            with open(utils.R8LIB_KEEP_RULES) as old_config:
                new_config.write(old_config.read().rstrip('\n') +
                                 '\n-optimizations !method/inlining/*\n')

    if not is_output_newer(utils.R8_JAR, r8lib_jar):
        r8lib_memory = os.path.join(tmpdir,
                                    'r8lib%s-memory.txt' % inline_suffix)
        build_r8lib.build_r8lib(output_path=r8lib_jar,
                                output_map=r8lib_map,
                                extra_args=r8lib_args,
                                track_memory_file=r8lib_memory)

    pg_output = os.path.join(tmpdir, 'r8lib-pg%s.jar' % inline_suffix)
    pg_memory = os.path.join(tmpdir, 'r8lib-pg%s-memory.txt' % inline_suffix)
    pg_map = os.path.join(tmpdir, 'r8lib-pg%s-map.txt' % inline_suffix)
    pg_args = [
        'tools/track_memory.sh', pg_memory,
        'third_party/proguard/proguard6.0.2/bin/proguard.sh', '@' + pg_config,
        '-lib', utils.RT_JAR, '-injar', utils.R8_JAR, '-printmapping', pg_map,
        '-outjar', pg_output
    ]
    for library_name, relocated_package in R8_RELOCATIONS:
        pg_args.extend([
            '-dontwarn', relocated_package + '.**', '-dontnote',
            relocated_package + '.**'
        ])
    check_call(pg_args)
    if threshold is None:
        threshold = 5
    toolhelper.run('jarsizecompare', [
        '--threshold',
        str(threshold), '--lib', utils.RT_JAR, '--input', 'input',
        utils.R8_JAR, '--input', 'r8', r8lib_jar, r8lib_map, '--input', 'pg',
        pg_output, pg_map
    ])
コード例 #4
0
ファイル: minify_tool.py プロジェクト: singhaditya28/r8
def minify_tool(mainclass=None, input_jar=utils.R8_JAR, output_jar=None,
                lib=utils.RT_JAR, debug=True, build=True, benchmark_name=None,
                track_memory_file=None):
  if output_jar is None:
    output_jar = generate_output_name(input_jar, mainclass)
  with utils.TempDir() as path:
    if mainclass:
      tmp_input_path = os.path.join(path, 'input.jar')
      repackage(input_jar, tmp_input_path, mainclass)
    else:
      tmp_input_path = input_jar
      mainclass = extract_mainclass(input_jar)
    keep_path = os.path.join(path, 'keep.txt')
    with open(keep_path, 'w') as fp:
      fp.write(KEEP % mainclass)
    args = ('--lib', lib,
            '--classfile',
            '--output', output_jar,
            '--pg-conf', keep_path,
            '--release',
            tmp_input_path)
    start_time = time.time()
    return_code = toolhelper.run('r8', args, debug=debug, build=build,
                                 track_memory_file=track_memory_file)
    if benchmark_name:
      elapsed_ms = 1000 * (time.time() - start_time)
      print('%s(RunTimeRaw): %s ms' % (benchmark_name, elapsed_ms))
      if track_memory_file:
        print('%s(MemoryUse): %s' %
              (benchmark_name, utils.grep_memoryuse(track_memory_file)))

    return return_code
コード例 #5
0
def extract_classes(input, output):
    if os.path.exists(output):
        shutil.rmtree(output)
    os.makedirs(output)
    args = ['--file-per-class', '--output', output]
    args.extend(input)
    if toolhelper.run('d8', args) is not 0:
        raise Exception('Failed running d8')
コード例 #6
0
def get_code_size(path):
    segments = toolhelper.run('dexsegments', [path],
                              build=False,
                              return_stdout=True)
    for line in segments.splitlines():
        if 'Code' in line:
            # The code size line looks like:
            #  - Code: 264 / 4
            splits = line.split(' ')
            return int(splits[3])
    # Some classes has no code.
    return 0
コード例 #7
0
def build_r8lib(target, exclude_deps, no_relocate, keep_rules_path,
    output_path, **kwargs):
  # Clean the build directory to ensure no repackaging of any existing
  # lib or deps.
  gradle.RunGradle(['clean'])
  lib_args = [target]
  deps_args = ['repackageDeps']
  if exclude_deps:
    lib_args.append('-Pexclude_deps')
  if no_relocate:
    lib_args.append('-Plib_no_relocate')
    deps_args.append('-Plib_no_relocate')
  # Produce the r8lib target to be processed later.
  gradle.RunGradle(lib_args)
  target_lib = os.path.join(utils.LIBS, target + '.jar')
  temp_lib = os.path.join(utils.LIBS, target + '_to_process.jar')
  os.rename(target_lib, temp_lib)
  # Produce the dependencies needed for running r8 on lib.jar.
  gradle.RunGradle(deps_args)
  temp_deps = os.path.join(utils.LIBS, target + 'lib_deps.jar')
  os.rename(DEPS_JAR, temp_deps)
  # Produce R8 for compiling lib
  if output_path is None:
    output_path = target + 'lib.jar'
  output_map_path = output_path + '.map'
  toolhelper.run(
      'r8',
      ('--release',
       '--classfile',
       '--lib', utils.RT_JAR,
       '--lib', temp_deps,
       temp_lib,
       '--output', output_path,
       '--pg-conf', keep_rules_path,
       '--pg-map-output', output_map_path),
      **kwargs)
  if exclude_deps:
    return [output_path, temp_deps]
  else:
    return [output_path]
コード例 #8
0
def dex(input, output):
    return_code = toolhelper.run('d8', [
        input,
        '--output',
        output,
        '--lib',
        utils.RT_JAR,
        '--min-api',
        '10000',
        '--no-desugaring',
    ],
                                 debug=False,
                                 build=False)
    if return_code != 0:
        sys.exit(return_code)
コード例 #9
0
ファイル: d8.py プロジェクト: raviagarwal7/r8
#!/usr/bin/env python
# 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.

import sys
import toolhelper

if __name__ == '__main__':
  sys.exit(toolhelper.run('d8', sys.argv[1:]))
コード例 #10
0
ファイル: d8logger.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('d8logger', sys.argv[1:]))
コード例 #11
0
ファイル: dexfilemerger.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
  sys.exit(toolhelper.run('dexfilemerger', sys.argv[1:]))
コード例 #12
0
ファイル: compatdx.py プロジェクト: singhaditya28/r8
#!/usr/bin/env python
# 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.

import sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('compatdx', sys.argv[1:]))
コード例 #13
0
ファイル: extractmarker.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('extractmarker', sys.argv[1:]))
コード例 #14
0
ファイル: run_on_app.py プロジェクト: newBoomer/r8
def run_with_options(options, args):
  app_provided_pg_conf = False;
  if options.golem:
    golem.link_third_party()
    options.out = os.getcwd()
  outdir = options.out
  data = None
  if options.app == 'gmscore':
    options.version = options.version or 'v9'
    data = gmscore_data
  elif options.app == 'nest':
    options.version = options.version or '20180926'
    data = nest_data
  elif options.app == 'youtube':
    options.version = options.version or '12.22'
    data = youtube_data
  elif options.app == 'chrome':
    options.version = options.version or 'default'
    data = chrome_data
  elif options.app == 'gmail':
    options.version = options.version or '170604.16'
    data = gmail_data
  else:
    raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))

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

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

  version = data.VERSIONS[options.version]

  if not options.type:
    options.type = 'deploy' if options.compiler == 'r8' \
        else 'proguarded'

  if options.type not in version:
    print('No type {} for version {}'.format(options.type, options.version))
    print('Valid types are {}'.format(version.keys()))
    return 1
  values = version[options.type]
  inputs = None
  # For R8 'deploy' the JAR is located using the Proguard configuration
  # -injars option. For chrome and nest we don't have the injars in the
  # proguard files.
  if 'inputs' in values and (options.compiler != 'r8'
                             or options.type != 'deploy'
                             or options.app == 'chrome'
                             or options.app == 'nest'):
    inputs = values['inputs']

  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']])

  if options.compiler == 'r8':
    if 'pgconf' in values and not options.k:
      for pgconf in values['pgconf']:
        args.extend(['--pg-conf', pgconf])
        app_provided_pg_conf = True
    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 not options.no_libraries and 'libraries' in values:
    for lib in values['libraries']:
      args.extend(['--lib', lib])

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

  # 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(' '))

  if inputs:
    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
        additional_pg_conf = GenerateAdditionalProguardConfiguration(
            temp, os.path.abspath(pg_outdir))
        args.extend(['--pg-conf', additional_pg_conf])
      build = not options.no_build and not options.golem
      exit_code = toolhelper.run(options.compiler, args,
                     build=build,
                     debug=not options.no_debug,
                     profile=options.profile,
                     track_memory_file=options.track_memory_to_file)
      if exit_code != 0:
        return exit_code

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

  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
コード例 #15
0
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('printuses', sys.argv[1:]))
コード例 #16
0
ファイル: bisect.py プロジェクト: singhaditya28/r8
#!/usr/bin/env python
# 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.

import sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('bisect', sys.argv[1:]))
コード例 #17
0
def run_with_options(options, args, extra_args=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):
        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()

    outdir = options.out
    data = None
    if options.app == 'gmscore':
        options.version = options.version or 'v9'
        data = gmscore_data
    elif options.app == 'nest':
        options.version = options.version or '20180926'
        data = nest_data
    elif options.app == 'youtube':
        options.version = options.version or '12.22'
        data = youtube_data
    elif options.app == 'chrome':
        options.version = options.version or '180917'
        data = chrome_data
    elif options.app == 'gmail':
        options.version = options.version or '170604.16'
        data = gmail_data
    else:
        raise Exception("You need to specify '--app={}'".format(
            '|'.join(APPS)))

    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 options.version in data.VERSIONS.keys():
        print('No version {} for application {}'.format(
            options.version, options.app))
        print('Valid versions are {}'.format(data.VERSIONS.keys()))
        return 1

    version = data.VERSIONS[options.version]

    if not options.type:
        options.type = 'deploy' if options.compiler == 'r8' \
            else 'proguarded'

    if options.type not in version:
        print('No type {} for version {}'.format(options.type,
                                                 options.version))
        print('Valid types are {}'.format(version.keys()))
        return 1
    values = version[options.type]
    inputs = None
    # For R8 'deploy' the JAR is located using the Proguard configuration
    # -injars option. For chrome and nest we don't have the injars in the
    # proguard files.
    if 'inputs' in values and (options.compiler != 'r8'
                               or options.type != 'deploy' or options.app
                               == 'chrome' or options.app == 'nest'):
        inputs = values['inputs']

    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']])

    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')
            sanitized_pgconf_path = os.path.join(os.path.abspath(outdir),
                                                 'sanitized.config')
            SanitizeLibraries(sanitized_lib_path, sanitized_pgconf_path,
                              values['pgconf'])
            args.extend(['--pg-conf', sanitized_pgconf_path])
            app_provided_pg_conf = True
        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')
        if 'proto-shrinking' in values:
            extra_args.append(
                '-Dcom.android.tools.r8.generatedExtensionRegistryShrinking=1')

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

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

    # 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(' '))

    if inputs:
        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
                additional_pg_conf = GenerateAdditionalProguardConfiguration(
                    temp, os.path.abspath(pg_outdir))
                args.extend(['--pg-conf', additional_pg_conf])
            build = not options.no_build and not options.golem
            stderr_path = os.path.join(temp, 'stderr')
            with open(stderr_path, 'w') as stderr:
                if options.compiler_build == 'full':
                    tool = options.compiler
                else:
                    assert (options.compiler_build == 'lib')
                    tool = 'r8lib-' + options.compiler
                exit_code = toolhelper.run(
                    tool,
                    args,
                    build=build,
                    debug=not options.no_debug,
                    profile=options.profile,
                    track_memory_file=options.track_memory_to_file,
                    extra_args=extra_args,
                    stderr=stderr,
                    timeout=options.timeout)
            if exit_code != 0:
                with open(stderr_path) as stderr:
                    stderr_text = stderr.read()
                    print(stderr_text)
                    if 'java.lang.OutOfMemoryError' in stderr_text:
                        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 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
コード例 #18
0
ファイル: compatproguard.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('compatproguard', sys.argv[1:]))
コード例 #19
0
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('printseeds', sys.argv[1:]))
コード例 #20
0
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('maindex', sys.argv[1:]))
コード例 #21
0
ファイル: disasm.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('disasm', sys.argv[1:], debug=False))
コード例 #22
0
ファイル: dexsegments.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
  sys.exit(toolhelper.run('dexsegments', sys.argv[1:]))
コード例 #23
0
ファイル: run_on_app.py プロジェクト: mateuszkrzeszowiec/r8
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')

    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]
    inputs = []
    # For R8 'deploy' the JAR is located using the Proguard configuration
    # -injars option. For chrome and nest we don't have the injars in the
    # proguard files.
    if 'inputs' in values and (options.compiler != 'r8' or type != 'deploy'
                               or options.app == 'chrome'
                               or options.app == 'nest' or options.app == 'r8'
                               or options.app == 'iosched'
                               or options.app == 'tachiyomi'):
        inputs = values['inputs']

    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']])

    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])
            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]
                    inputs = values['inputs']
            app_provided_pg_conf = True
        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])
            build = not options.no_build and not options.golem
            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=build,
                    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 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
コード例 #24
0
ファイル: jardiff.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('jardiff', sys.argv[1:]))
コード例 #25
0
ファイル: dexsplitter.py プロジェクト: singhaditya28/r8
#!/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 sys
import toolhelper

if __name__ == '__main__':
    sys.exit(toolhelper.run('dexsplitter', sys.argv[1:]))