File: compile_kt.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (180 lines) | stat: -rwxr-xr-x 6,239 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env python3
#
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import logging
import os
import shutil
import sys
import time

import compile_java

from util import build_utils
import action_helpers  # build_utils adds //build to sys.path.


def _RunCompiler(args,
                 kotlinc_cmd,
                 source_files,
                 jar_path,
                 intermediates_out_dir=None):
  """Runs the Kotlin compiler."""
  logging.info('Starting _RunCompiler')

  source_files = source_files.copy()
  kt_files = [f for f in source_files if f.endswith('.kt')]
  assert len(kt_files) > 0, 'At least one .kt file must be passed in.'

  java_srcjars = args.java_srcjars

  # Use jar_path's directory to ensure paths are relative (needed for rbe).
  temp_dir = jar_path + '.staging'
  build_utils.DeleteDirectory(temp_dir)
  os.makedirs(temp_dir)
  try:
    classes_dir = os.path.join(temp_dir, 'classes')
    os.makedirs(classes_dir)

    input_srcjars_dir = os.path.join(intermediates_out_dir or temp_dir,
                                     'input_srcjars')

    if java_srcjars:
      logging.info('Extracting srcjars to %s', input_srcjars_dir)
      build_utils.MakeDirectory(input_srcjars_dir)
      for srcjar in args.java_srcjars:
        source_files += build_utils.ExtractAll(srcjar,
                                               no_clobber=True,
                                               path=input_srcjars_dir,
                                               pattern='*.java')
      logging.info('Done extracting srcjars')

    # Don't include the output directory in the initial set of args since it
    # being in a temp dir makes it unstable (breaks md5 stamping).
    cmd = list(kotlinc_cmd)
    cmd += ['-d', classes_dir]

    if args.classpath:
      cmd += ['-classpath', ':'.join(args.classpath)]

    # This a kotlinc plugin to generate header files for .kt files, similar to
    # turbine for .java files.
    jvm_abi_path = os.path.join(build_utils.KOTLIN_HOME, 'lib',
                                'jvm-abi-gen.jar')
    cmd += [
        f'-Xplugin={jvm_abi_path}', '-P',
        'plugin:org.jetbrains.kotlin.jvm.abi:outputDir=' +
        args.interface_jar_path
    ]

    # Pass source paths as response files to avoid extremely long command
    # lines that are tedius to debug.
    source_files_rsp_path = os.path.join(temp_dir, 'files_list.txt')
    with open(source_files_rsp_path, 'w', encoding='utf-8') as f:
      f.write(' '.join(source_files))
    cmd += ['@' + source_files_rsp_path]

    # Explicitly set JAVA_HOME since some bots do not have this already set.
    env = os.environ.copy()
    env['JAVA_HOME'] = build_utils.JAVA_HOME

    logging.debug('Build command %s', cmd)
    start = time.time()
    build_utils.CheckOutput(cmd,
                            env=env,
                            print_stdout=args.chromium_code,
                            fail_on_output=args.warnings_as_errors)
    logging.info('Kotlin compilation took %ss', time.time() - start)

    compile_java.CreateJarFile(jar_path, classes_dir)

    logging.info('Completed all steps in _RunCompiler')
  finally:
    shutil.rmtree(temp_dir)


def _ParseOptions(argv):
  parser = argparse.ArgumentParser()
  action_helpers.add_depfile_arg(parser)

  parser.add_argument('--java-srcjars',
                      action='append',
                      default=[],
                      help='List of srcjars to include in compilation.')
  parser.add_argument(
      '--generated-dir',
      help='Subdirectory within target_gen_dir to place extracted srcjars and '
      'annotation processor output for codesearch to find.')
  parser.add_argument('--classpath', action='append', help='Classpath to use.')
  parser.add_argument(
      '--chromium-code',
      action='store_true',
      help='Whether code being compiled should be built with stricter '
      'warnings for chromium code.')
  parser.add_argument('--warnings-as-errors',
                      action='store_true',
                      help='Treat all warnings as errors.')
  parser.add_argument('--jar-path', help='Jar output path.', required=True)
  parser.add_argument('--interface-jar-path',
                      help='Interface jar output path.',
                      required=True)

  args, extra_args = parser.parse_known_args(argv)

  args.classpath = action_helpers.parse_gn_list(args.classpath)
  args.java_srcjars = action_helpers.parse_gn_list(args.java_srcjars)

  source_files = []
  for arg in extra_args:
    # Interpret a path prefixed with @ as a file containing a list of sources.
    if arg.startswith('@'):
      source_files.extend(build_utils.ReadSourcesList(arg[1:]))
    else:
      assert not arg.startswith('--'), f'Undefined option {arg}'
      source_files.append(arg)

  return args, source_files


def main(argv):
  build_utils.InitLogging('KOTLINC_DEBUG')
  argv = build_utils.ExpandFileArgs(argv)
  args, source_files = _ParseOptions(argv)

  kotlinc_cmd = [build_utils.KOTLINC_PATH]

  kotlinc_cmd += [
      '-no-jdk',  # Avoid depending on the bundled JDK.
      # Avoid depending on the bundled Kotlin stdlib. This may have a version
      # skew with the one in //third_party/android_deps (which is the one we
      # prefer to use).
      '-no-stdlib',
      # Avoid depending on the bundled Kotlin reflect libs.
      '-no-reflect',
      # We typically set a default of 1G for java commands, see
      # build_utils.JavaCmd. This may help prevent OOMs.
      '-J-Xmx1G',
  ]

  if args.generated_dir:
    # Delete any stale files in the generated directory. The purpose of
    # args.generated_dir is for codesearch.
    shutil.rmtree(args.generated_dir, True)

  _RunCompiler(args,
               kotlinc_cmd,
               source_files,
               args.jar_path,
               intermediates_out_dir=args.generated_dir)

  if args.depfile:
    # GN already knows of the source files, so avoid listing individual files
    # in the depfile.
    action_helpers.write_depfile(args.depfile, args.jar_path, args.classpath)


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