1#!/usr/bin/env python
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, min_api, desugar_jdk_libs_json, desugar_jdk_libs_jar,
38                 desugar_jdk_libs_configuration_jar, keep_rule_file, output,
39                 warnings_as_errors):
40  # TODO(agrieve): Spews a lot of stderr about missing classes.
41  with build_utils.TempDir() as tmp_dir:
42    cmd = build_utils.JavaCmd(warnings_as_errors) + [
43        '-cp',
44        r8_path,
45        'com.android.tools.r8.L8',
46        '--min-api',
47        min_api,
48        '--lib',
49        build_utils.JAVA_HOME,
50        '--desugared-lib',
51        desugar_jdk_libs_json,
52    ]
53
54    # If no desugaring is required, no keep rules are generated, and the keep
55    # file will not be created.
56    if keep_rule_file is not None and os.path.exists(keep_rule_file):
57      cmd += ['--pg-conf', keep_rule_file]
58
59    cmd += [
60        '--output', tmp_dir, desugar_jdk_libs_jar,
61        desugar_jdk_libs_configuration_jar
62    ]
63
64    build_utils.CheckOutput(cmd,
65                            print_stdout=True,
66                            fail_on_output=warnings_as_errors)
67    if os.path.exists(os.path.join(tmp_dir, 'classes2.dex')):
68      raise Exception('Achievement unlocked: desugar_jdk_libs is multidex!')
69
70    # classes.dex might not exists if the "desugar_jdk_libs_jar" is not used
71    # at all.
72    if os.path.exists(os.path.join(tmp_dir, 'classes.dex')):
73      shutil.move(os.path.join(tmp_dir, 'classes.dex'), output)
74      return True
75    return False
76
77
78def main(args):
79  options = _ParseArgs(args)
80  DexJdkLibJar(options.r8_path, options.min_api, options.desugar_jdk_libs_json,
81               options.desugar_jdk_libs_jar,
82               options.desugar_jdk_libs_configuration_jar, None, options.output,
83               options.warnings_as_errors)
84
85
86if __name__ == '__main__':
87  main(sys.argv[1:])
88