1#!/usr/bin/env python3
2#
3# Copyright 2020 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import argparse
8import os
9import shutil
10import subprocess
11import sys
12import zipfile
13
14from util import build_utils
15
16
17def _ParseArgs(args):
18  args = build_utils.ExpandFileArgs(args)
19  parser = argparse.ArgumentParser()
20
21  parser.add_argument('--output', required=True, help='Dex output path.')
22  parser.add_argument('--r8-path', required=True, help='Path to R8 jar.')
23  parser.add_argument(
24      '--desugar-jdk-libs-json', help='Path to desugar_jdk_libs.json.')
25  parser.add_argument(
26      '--desugar-jdk-libs-jar', help='Path to desugar_jdk_libs.jar.')
27  parser.add_argument('--desugar-jdk-libs-configuration-jar',
28                      help='Path to desugar_jdk_libs_configuration.jar.')
29  parser.add_argument('--min-api', help='minSdkVersion', required=True)
30  parser.add_argument('--warnings-as-errors',
31                      action='store_true',
32                      help='Treat all warnings as errors.')
33  options = parser.parse_args(args)
34  return options
35
36
37def DexJdkLibJar(r8_path,
38                 min_api,
39                 desugar_jdk_libs_json,
40                 desugar_jdk_libs_jar,
41                 desugar_jdk_libs_configuration_jar,
42                 output,
43                 warnings_as_errors,
44                 config_paths=None):
45  # TODO(agrieve): Spews a lot of stderr about missing classes.
46  with build_utils.TempDir() as tmp_dir:
47    cmd = build_utils.JavaCmd(warnings_as_errors) + [
48        '-cp',
49        r8_path,
50        'com.android.tools.r8.L8',
51        '--min-api',
52        min_api,
53        '--lib',
54        build_utils.JAVA_HOME,
55        '--desugared-lib',
56        desugar_jdk_libs_json,
57    ]
58
59    # If no desugaring is required, no keep rules are generated, and the keep
60    # file will not be created.
61    if config_paths is not None:
62      for path in config_paths:
63        cmd += ['--pg-conf', path]
64
65    cmd += [
66        '--output', tmp_dir, desugar_jdk_libs_jar,
67        desugar_jdk_libs_configuration_jar
68    ]
69
70    build_utils.CheckOutput(cmd,
71                            print_stdout=True,
72                            fail_on_output=warnings_as_errors)
73    if os.path.exists(os.path.join(tmp_dir, 'classes2.dex')):
74      raise Exception('Achievement unlocked: desugar_jdk_libs is multidex!')
75
76    # classes.dex might not exists if the "desugar_jdk_libs_jar" is not used
77    # at all.
78    if os.path.exists(os.path.join(tmp_dir, 'classes.dex')):
79      shutil.move(os.path.join(tmp_dir, 'classes.dex'), output)
80      return True
81    return False
82
83
84def main(args):
85  options = _ParseArgs(args)
86  DexJdkLibJar(options.r8_path, options.min_api, options.desugar_jdk_libs_json,
87               options.desugar_jdk_libs_jar,
88               options.desugar_jdk_libs_configuration_jar, options.output,
89               options.warnings_as_errors)
90
91
92if __name__ == '__main__':
93  main(sys.argv[1:])
94