xref: /aosp_15_r20/external/angle/build/android/gyp/turbine.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2020 The Chromium Authors
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker"""Wraps the turbine jar and expands @FileArgs."""
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Workerimport argparse
8*8975f5c5SAndroid Build Coastguard Workerimport functools
9*8975f5c5SAndroid Build Coastguard Workerimport logging
10*8975f5c5SAndroid Build Coastguard Workerimport sys
11*8975f5c5SAndroid Build Coastguard Workerimport time
12*8975f5c5SAndroid Build Coastguard Workerimport zipfile
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Workerimport compile_java
15*8975f5c5SAndroid Build Coastguard Workerimport javac_output_processor
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 Workerimport zip_helpers
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Workerdef ProcessJavacOutput(output, target_name):
22*8975f5c5SAndroid Build Coastguard Worker  output_processor = javac_output_processor.JavacOutputProcessor(target_name)
23*8975f5c5SAndroid Build Coastguard Worker  lines = output_processor.Process(output.split('\n'))
24*8975f5c5SAndroid Build Coastguard Worker  return '\n'.join(lines)
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Workerdef main(argv):
28*8975f5c5SAndroid Build Coastguard Worker  build_utils.InitLogging('TURBINE_DEBUG')
29*8975f5c5SAndroid Build Coastguard Worker  argv = build_utils.ExpandFileArgs(argv[1:])
30*8975f5c5SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
31*8975f5c5SAndroid Build Coastguard Worker  action_helpers.add_depfile_arg(parser)
32*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--target-name', help='Fully qualified GN target name.')
33*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
34*8975f5c5SAndroid Build Coastguard Worker      '--turbine-jar-path', required=True, help='Path to the turbine jar file.')
35*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
36*8975f5c5SAndroid Build Coastguard Worker      '--java-srcjars',
37*8975f5c5SAndroid Build Coastguard Worker      action='append',
38*8975f5c5SAndroid Build Coastguard Worker      default=[],
39*8975f5c5SAndroid Build Coastguard Worker      help='List of srcjars to include in compilation.')
40*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--classpath', action='append', help='Classpath to use.')
41*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
42*8975f5c5SAndroid Build Coastguard Worker      '--processors',
43*8975f5c5SAndroid Build Coastguard Worker      action='append',
44*8975f5c5SAndroid Build Coastguard Worker      help='GN list of annotation processor main classes.')
45*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
46*8975f5c5SAndroid Build Coastguard Worker      '--processorpath',
47*8975f5c5SAndroid Build Coastguard Worker      action='append',
48*8975f5c5SAndroid Build Coastguard Worker      help='GN list of jars that comprise the classpath used for Annotation '
49*8975f5c5SAndroid Build Coastguard Worker      'Processors.')
50*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
51*8975f5c5SAndroid Build Coastguard Worker      '--processor-args',
52*8975f5c5SAndroid Build Coastguard Worker      action='append',
53*8975f5c5SAndroid Build Coastguard Worker      help='key=value arguments for the annotation processors.')
54*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--jar-path', help='Jar output path.', required=True)
55*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
56*8975f5c5SAndroid Build Coastguard Worker      '--generated-jar-path',
57*8975f5c5SAndroid Build Coastguard Worker      required=True,
58*8975f5c5SAndroid Build Coastguard Worker      help='Output path for generated source files.')
59*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--warnings-as-errors',
60*8975f5c5SAndroid Build Coastguard Worker                      action='store_true',
61*8975f5c5SAndroid Build Coastguard Worker                      help='Treat all warnings as errors.')
62*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--kotlin-jar-path',
63*8975f5c5SAndroid Build Coastguard Worker                      help='Kotlin jar to be merged into the output jar.')
64*8975f5c5SAndroid Build Coastguard Worker  options, unknown_args = parser.parse_known_args(argv)
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker  options.classpath = action_helpers.parse_gn_list(options.classpath)
67*8975f5c5SAndroid Build Coastguard Worker  options.processorpath = action_helpers.parse_gn_list(options.processorpath)
68*8975f5c5SAndroid Build Coastguard Worker  options.processors = action_helpers.parse_gn_list(options.processors)
69*8975f5c5SAndroid Build Coastguard Worker  options.java_srcjars = action_helpers.parse_gn_list(options.java_srcjars)
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker  files = []
72*8975f5c5SAndroid Build Coastguard Worker  for arg in unknown_args:
73*8975f5c5SAndroid Build Coastguard Worker    # Interpret a path prefixed with @ as a file containing a list of sources.
74*8975f5c5SAndroid Build Coastguard Worker    if arg.startswith('@'):
75*8975f5c5SAndroid Build Coastguard Worker      files.extend(build_utils.ReadSourcesList(arg[1:]))
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Worker  # The target's .sources file contains both Java and Kotlin files. We use
78*8975f5c5SAndroid Build Coastguard Worker  # compile_kt.py to compile the Kotlin files to .class and header jars.
79*8975f5c5SAndroid Build Coastguard Worker  # Turbine is run only on .java files.
80*8975f5c5SAndroid Build Coastguard Worker  java_files = [f for f in files if f.endswith('.java')]
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker  cmd = build_utils.JavaCmd() + [
83*8975f5c5SAndroid Build Coastguard Worker      '-classpath', options.turbine_jar_path, 'com.google.turbine.main.Main'
84*8975f5c5SAndroid Build Coastguard Worker  ]
85*8975f5c5SAndroid Build Coastguard Worker  javac_cmd = ['--release', '17']
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker  # Turbine reads lists from command line args by consuming args until one
88*8975f5c5SAndroid Build Coastguard Worker  # starts with double dash (--). Thus command line args should be grouped
89*8975f5c5SAndroid Build Coastguard Worker  # together and passed in together.
90*8975f5c5SAndroid Build Coastguard Worker  if options.processors:
91*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--processors']
92*8975f5c5SAndroid Build Coastguard Worker    cmd += options.processors
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker  if options.processorpath:
95*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--processorpath']
96*8975f5c5SAndroid Build Coastguard Worker    cmd += options.processorpath
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker  if options.processor_args:
99*8975f5c5SAndroid Build Coastguard Worker    for arg in options.processor_args:
100*8975f5c5SAndroid Build Coastguard Worker      javac_cmd.extend(['-A%s' % arg])
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker  if options.classpath:
103*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--classpath']
104*8975f5c5SAndroid Build Coastguard Worker    cmd += options.classpath
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker  if options.java_srcjars:
107*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--source_jars']
108*8975f5c5SAndroid Build Coastguard Worker    cmd += options.java_srcjars
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker  if java_files:
111*8975f5c5SAndroid Build Coastguard Worker    # Use jar_path to ensure paths are relative (needed for rbe).
112*8975f5c5SAndroid Build Coastguard Worker    files_rsp_path = options.jar_path + '.java_files_list.txt'
113*8975f5c5SAndroid Build Coastguard Worker    with open(files_rsp_path, 'w') as f:
114*8975f5c5SAndroid Build Coastguard Worker      f.write('\n'.join(java_files))
115*8975f5c5SAndroid Build Coastguard Worker    # Pass source paths as response files to avoid extremely long command
116*8975f5c5SAndroid Build Coastguard Worker    # lines that are tedius to debug.
117*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--sources']
118*8975f5c5SAndroid Build Coastguard Worker    cmd += ['@' + files_rsp_path]
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker  cmd += ['--javacopts']
121*8975f5c5SAndroid Build Coastguard Worker  cmd += javac_cmd
122*8975f5c5SAndroid Build Coastguard Worker  cmd += ['--']  # Terminate javacopts
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker  # Use AtomicOutput so that output timestamps are not updated when outputs
125*8975f5c5SAndroid Build Coastguard Worker  # are not changed.
126*8975f5c5SAndroid Build Coastguard Worker  with action_helpers.atomic_output(options.jar_path) as output_jar, \
127*8975f5c5SAndroid Build Coastguard Worker      action_helpers.atomic_output(options.generated_jar_path) as gensrc_jar:
128*8975f5c5SAndroid Build Coastguard Worker    cmd += ['--output', output_jar.name, '--gensrc_output', gensrc_jar.name]
129*8975f5c5SAndroid Build Coastguard Worker    process_javac_output_partial = functools.partial(
130*8975f5c5SAndroid Build Coastguard Worker        ProcessJavacOutput, target_name=options.target_name)
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker    logging.debug('Command: %s', cmd)
133*8975f5c5SAndroid Build Coastguard Worker    start = time.time()
134*8975f5c5SAndroid Build Coastguard Worker    try:
135*8975f5c5SAndroid Build Coastguard Worker      build_utils.CheckOutput(cmd,
136*8975f5c5SAndroid Build Coastguard Worker                              print_stdout=True,
137*8975f5c5SAndroid Build Coastguard Worker                              stdout_filter=process_javac_output_partial,
138*8975f5c5SAndroid Build Coastguard Worker                              stderr_filter=process_javac_output_partial,
139*8975f5c5SAndroid Build Coastguard Worker                              fail_on_output=options.warnings_as_errors)
140*8975f5c5SAndroid Build Coastguard Worker    except build_utils.CalledProcessError as e:
141*8975f5c5SAndroid Build Coastguard Worker      # Do not output stacktrace as it takes up space on gerrit UI, forcing
142*8975f5c5SAndroid Build Coastguard Worker      # you to click though to find the actual compilation error. It's never
143*8975f5c5SAndroid Build Coastguard Worker      # interesting to see the Python stacktrace for a Java compilation error.
144*8975f5c5SAndroid Build Coastguard Worker      sys.stderr.write(e.output)
145*8975f5c5SAndroid Build Coastguard Worker      sys.exit(1)
146*8975f5c5SAndroid Build Coastguard Worker    end = time.time() - start
147*8975f5c5SAndroid Build Coastguard Worker    logging.info('Header compilation took %ss', end)
148*8975f5c5SAndroid Build Coastguard Worker    if options.kotlin_jar_path:
149*8975f5c5SAndroid Build Coastguard Worker      with zipfile.ZipFile(output_jar.name, 'a') as out_zip:
150*8975f5c5SAndroid Build Coastguard Worker        path_transform = lambda p: p if p.endswith('.class') else None
151*8975f5c5SAndroid Build Coastguard Worker        zip_helpers.merge_zips(out_zip, [options.kotlin_jar_path],
152*8975f5c5SAndroid Build Coastguard Worker                               path_transform=path_transform)
153*8975f5c5SAndroid Build Coastguard Worker
154*8975f5c5SAndroid Build Coastguard Worker  if options.depfile:
155*8975f5c5SAndroid Build Coastguard Worker    # GN already knows of the java files, so avoid listing individual java files
156*8975f5c5SAndroid Build Coastguard Worker    # in the depfile.
157*8975f5c5SAndroid Build Coastguard Worker    depfile_deps = (options.classpath + options.processorpath +
158*8975f5c5SAndroid Build Coastguard Worker                    options.java_srcjars)
159*8975f5c5SAndroid Build Coastguard Worker    action_helpers.write_depfile(options.depfile, options.jar_path,
160*8975f5c5SAndroid Build Coastguard Worker                                 depfile_deps)
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
164*8975f5c5SAndroid Build Coastguard Worker  sys.exit(main(sys.argv))
165