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