xref: /aosp_15_r20/external/angle/build/android/gyp/compile_kt.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker#
3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2023 The Chromium Authors
4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Workerimport argparse
8*8975f5c5SAndroid Build Coastguard Workerimport logging
9*8975f5c5SAndroid Build Coastguard Workerimport os
10*8975f5c5SAndroid Build Coastguard Workerimport shutil
11*8975f5c5SAndroid Build Coastguard Workerimport sys
12*8975f5c5SAndroid Build Coastguard Workerimport time
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Workerimport compile_java
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils
17*8975f5c5SAndroid Build Coastguard Workerimport action_helpers  # build_utils adds //build to sys.path.
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Workerdef _RunCompiler(args,
21*8975f5c5SAndroid Build Coastguard Worker                 kotlinc_cmd,
22*8975f5c5SAndroid Build Coastguard Worker                 source_files,
23*8975f5c5SAndroid Build Coastguard Worker                 jar_path,
24*8975f5c5SAndroid Build Coastguard Worker                 intermediates_out_dir=None):
25*8975f5c5SAndroid Build Coastguard Worker  """Runs the Kotlin compiler."""
26*8975f5c5SAndroid Build Coastguard Worker  logging.info('Starting _RunCompiler')
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker  source_files = source_files.copy()
29*8975f5c5SAndroid Build Coastguard Worker  kt_files = [f for f in source_files if f.endswith('.kt')]
30*8975f5c5SAndroid Build Coastguard Worker  assert len(kt_files) > 0, 'At least one .kt file must be passed in.'
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker  java_srcjars = args.java_srcjars
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker  # Use jar_path's directory to ensure paths are relative (needed for rbe).
35*8975f5c5SAndroid Build Coastguard Worker  temp_dir = jar_path + '.staging'
36*8975f5c5SAndroid Build Coastguard Worker  build_utils.DeleteDirectory(temp_dir)
37*8975f5c5SAndroid Build Coastguard Worker  os.makedirs(temp_dir)
38*8975f5c5SAndroid Build Coastguard Worker  try:
39*8975f5c5SAndroid Build Coastguard Worker    classes_dir = os.path.join(temp_dir, 'classes')
40*8975f5c5SAndroid Build Coastguard Worker    os.makedirs(classes_dir)
41*8975f5c5SAndroid Build Coastguard Worker
42*8975f5c5SAndroid Build Coastguard Worker    input_srcjars_dir = os.path.join(intermediates_out_dir or temp_dir,
43*8975f5c5SAndroid Build Coastguard Worker                                     'input_srcjars')
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker    if java_srcjars:
46*8975f5c5SAndroid Build Coastguard Worker      logging.info('Extracting srcjars to %s', input_srcjars_dir)
47*8975f5c5SAndroid Build Coastguard Worker      build_utils.MakeDirectory(input_srcjars_dir)
48*8975f5c5SAndroid Build Coastguard Worker      for srcjar in args.java_srcjars:
49*8975f5c5SAndroid Build Coastguard Worker        source_files += build_utils.ExtractAll(srcjar,
50*8975f5c5SAndroid Build Coastguard Worker                                               no_clobber=True,
51*8975f5c5SAndroid Build Coastguard Worker                                               path=input_srcjars_dir,
52*8975f5c5SAndroid Build Coastguard Worker                                               pattern='*.java')
53*8975f5c5SAndroid Build Coastguard Worker      logging.info('Done extracting srcjars')
54*8975f5c5SAndroid Build Coastguard Worker
55*8975f5c5SAndroid Build Coastguard Worker    # Don't include the output directory in the initial set of args since it
56*8975f5c5SAndroid Build Coastguard Worker    # being in a temp dir makes it unstable (breaks md5 stamping).
57*8975f5c5SAndroid Build Coastguard Worker    cmd = list(kotlinc_cmd)
58*8975f5c5SAndroid Build Coastguard Worker    cmd += ['-d', classes_dir]
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker    if args.classpath:
61*8975f5c5SAndroid Build Coastguard Worker      cmd += ['-classpath', ':'.join(args.classpath)]
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker    # This a kotlinc plugin to generate header files for .kt files, similar to
64*8975f5c5SAndroid Build Coastguard Worker    # turbine for .java files.
65*8975f5c5SAndroid Build Coastguard Worker    jvm_abi_path = os.path.join(build_utils.KOTLIN_HOME, 'lib',
66*8975f5c5SAndroid Build Coastguard Worker                                'jvm-abi-gen.jar')
67*8975f5c5SAndroid Build Coastguard Worker    cmd += [
68*8975f5c5SAndroid Build Coastguard Worker        f'-Xplugin={jvm_abi_path}', '-P',
69*8975f5c5SAndroid Build Coastguard Worker        'plugin:org.jetbrains.kotlin.jvm.abi:outputDir=' +
70*8975f5c5SAndroid Build Coastguard Worker        args.interface_jar_path
71*8975f5c5SAndroid Build Coastguard Worker    ]
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Worker    # Pass source paths as response files to avoid extremely long command
74*8975f5c5SAndroid Build Coastguard Worker    # lines that are tedius to debug.
75*8975f5c5SAndroid Build Coastguard Worker    source_files_rsp_path = os.path.join(temp_dir, 'files_list.txt')
76*8975f5c5SAndroid Build Coastguard Worker    with open(source_files_rsp_path, 'w') as f:
77*8975f5c5SAndroid Build Coastguard Worker      f.write(' '.join(source_files))
78*8975f5c5SAndroid Build Coastguard Worker    cmd += ['@' + source_files_rsp_path]
79*8975f5c5SAndroid Build Coastguard Worker
80*8975f5c5SAndroid Build Coastguard Worker    # Explicitly set JAVA_HOME since some bots do not have this already set.
81*8975f5c5SAndroid Build Coastguard Worker    env = os.environ.copy()
82*8975f5c5SAndroid Build Coastguard Worker    env['JAVA_HOME'] = build_utils.JAVA_HOME
83*8975f5c5SAndroid Build Coastguard Worker
84*8975f5c5SAndroid Build Coastguard Worker    logging.debug('Build command %s', cmd)
85*8975f5c5SAndroid Build Coastguard Worker    start = time.time()
86*8975f5c5SAndroid Build Coastguard Worker    build_utils.CheckOutput(cmd,
87*8975f5c5SAndroid Build Coastguard Worker                            env=env,
88*8975f5c5SAndroid Build Coastguard Worker                            print_stdout=args.chromium_code,
89*8975f5c5SAndroid Build Coastguard Worker                            fail_on_output=args.warnings_as_errors)
90*8975f5c5SAndroid Build Coastguard Worker    logging.info('Kotlin compilation took %ss', time.time() - start)
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker    compile_java.CreateJarFile(jar_path, classes_dir)
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker    logging.info('Completed all steps in _RunCompiler')
95*8975f5c5SAndroid Build Coastguard Worker  finally:
96*8975f5c5SAndroid Build Coastguard Worker    shutil.rmtree(temp_dir)
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker
99*8975f5c5SAndroid Build Coastguard Workerdef _ParseOptions(argv):
100*8975f5c5SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
101*8975f5c5SAndroid Build Coastguard Worker  action_helpers.add_depfile_arg(parser)
102*8975f5c5SAndroid Build Coastguard Worker
103*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--java-srcjars',
104*8975f5c5SAndroid Build Coastguard Worker                      action='append',
105*8975f5c5SAndroid Build Coastguard Worker                      default=[],
106*8975f5c5SAndroid Build Coastguard Worker                      help='List of srcjars to include in compilation.')
107*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
108*8975f5c5SAndroid Build Coastguard Worker      '--generated-dir',
109*8975f5c5SAndroid Build Coastguard Worker      help='Subdirectory within target_gen_dir to place extracted srcjars and '
110*8975f5c5SAndroid Build Coastguard Worker      'annotation processor output for codesearch to find.')
111*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--classpath', action='append', help='Classpath to use.')
112*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
113*8975f5c5SAndroid Build Coastguard Worker      '--chromium-code',
114*8975f5c5SAndroid Build Coastguard Worker      action='store_true',
115*8975f5c5SAndroid Build Coastguard Worker      help='Whether code being compiled should be built with stricter '
116*8975f5c5SAndroid Build Coastguard Worker      'warnings for chromium code.')
117*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--warnings-as-errors',
118*8975f5c5SAndroid Build Coastguard Worker                      action='store_true',
119*8975f5c5SAndroid Build Coastguard Worker                      help='Treat all warnings as errors.')
120*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--jar-path', help='Jar output path.', required=True)
121*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--interface-jar-path',
122*8975f5c5SAndroid Build Coastguard Worker                      help='Interface jar output path.',
123*8975f5c5SAndroid Build Coastguard Worker                      required=True)
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker  args, extra_args = parser.parse_known_args(argv)
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker  args.classpath = action_helpers.parse_gn_list(args.classpath)
128*8975f5c5SAndroid Build Coastguard Worker  args.java_srcjars = action_helpers.parse_gn_list(args.java_srcjars)
129*8975f5c5SAndroid Build Coastguard Worker
130*8975f5c5SAndroid Build Coastguard Worker  source_files = []
131*8975f5c5SAndroid Build Coastguard Worker  for arg in extra_args:
132*8975f5c5SAndroid Build Coastguard Worker    # Interpret a path prefixed with @ as a file containing a list of sources.
133*8975f5c5SAndroid Build Coastguard Worker    if arg.startswith('@'):
134*8975f5c5SAndroid Build Coastguard Worker      source_files.extend(build_utils.ReadSourcesList(arg[1:]))
135*8975f5c5SAndroid Build Coastguard Worker    else:
136*8975f5c5SAndroid Build Coastguard Worker      assert not arg.startswith('--'), f'Undefined option {arg}'
137*8975f5c5SAndroid Build Coastguard Worker      source_files.append(arg)
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker  return args, source_files
140*8975f5c5SAndroid Build Coastguard Worker
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Workerdef main(argv):
143*8975f5c5SAndroid Build Coastguard Worker  build_utils.InitLogging('KOTLINC_DEBUG')
144*8975f5c5SAndroid Build Coastguard Worker  argv = build_utils.ExpandFileArgs(argv)
145*8975f5c5SAndroid Build Coastguard Worker  args, source_files = _ParseOptions(argv)
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Worker  kotlinc_cmd = [build_utils.KOTLINC_PATH]
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker  kotlinc_cmd += [
150*8975f5c5SAndroid Build Coastguard Worker      '-no-jdk',  # Avoid depending on the bundled JDK.
151*8975f5c5SAndroid Build Coastguard Worker      # Avoid depending on the bundled Kotlin stdlib. This may have a version
152*8975f5c5SAndroid Build Coastguard Worker      # skew with the one in //third_party/android_deps (which is the one we
153*8975f5c5SAndroid Build Coastguard Worker      # prefer to use).
154*8975f5c5SAndroid Build Coastguard Worker      '-no-stdlib',
155*8975f5c5SAndroid Build Coastguard Worker      # Avoid depending on the bundled Kotlin reflect libs.
156*8975f5c5SAndroid Build Coastguard Worker      '-no-reflect',
157*8975f5c5SAndroid Build Coastguard Worker      # We typically set a default of 1G for java commands, see
158*8975f5c5SAndroid Build Coastguard Worker      # build_utils.JavaCmd. This may help prevent OOMs.
159*8975f5c5SAndroid Build Coastguard Worker      '-J-Xmx1G',
160*8975f5c5SAndroid Build Coastguard Worker  ]
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker  if args.generated_dir:
163*8975f5c5SAndroid Build Coastguard Worker    # Delete any stale files in the generated directory. The purpose of
164*8975f5c5SAndroid Build Coastguard Worker    # args.generated_dir is for codesearch.
165*8975f5c5SAndroid Build Coastguard Worker    shutil.rmtree(args.generated_dir, True)
166*8975f5c5SAndroid Build Coastguard Worker
167*8975f5c5SAndroid Build Coastguard Worker  _RunCompiler(args,
168*8975f5c5SAndroid Build Coastguard Worker               kotlinc_cmd,
169*8975f5c5SAndroid Build Coastguard Worker               source_files,
170*8975f5c5SAndroid Build Coastguard Worker               args.jar_path,
171*8975f5c5SAndroid Build Coastguard Worker               intermediates_out_dir=args.generated_dir)
172*8975f5c5SAndroid Build Coastguard Worker
173*8975f5c5SAndroid Build Coastguard Worker  if args.depfile:
174*8975f5c5SAndroid Build Coastguard Worker    # GN already knows of the source files, so avoid listing individual files
175*8975f5c5SAndroid Build Coastguard Worker    # in the depfile.
176*8975f5c5SAndroid Build Coastguard Worker    action_helpers.write_depfile(args.depfile, args.jar_path, args.classpath)
177*8975f5c5SAndroid Build Coastguard Worker
178*8975f5c5SAndroid Build Coastguard Worker
179*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
180*8975f5c5SAndroid Build Coastguard Worker  sys.exit(main(sys.argv[1:]))
181