169 lines
6.1 KiB
Python
Executable File
169 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright 2020 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
"""Wraps the turbine jar and expands @FileArgs."""
|
|
|
|
import argparse
|
|
import functools
|
|
import logging
|
|
import sys
|
|
import time
|
|
import zipfile
|
|
|
|
import compile_java
|
|
import javac_output_processor
|
|
from util import build_utils
|
|
import action_helpers # build_utils adds //build to sys.path.
|
|
import zip_helpers
|
|
|
|
|
|
def ProcessJavacOutput(output, target_name):
|
|
output_processor = javac_output_processor.JavacOutputProcessor(target_name)
|
|
lines = output_processor.Process(output.split('\n'))
|
|
return '\n'.join(lines)
|
|
|
|
|
|
def main(argv):
|
|
build_utils.InitLogging('TURBINE_DEBUG')
|
|
argv = build_utils.ExpandFileArgs(argv[1:])
|
|
parser = argparse.ArgumentParser()
|
|
action_helpers.add_depfile_arg(parser)
|
|
parser.add_argument('--target-name', help='Fully qualified GN target name.')
|
|
parser.add_argument(
|
|
'--turbine-jar-path', required=True, help='Path to the turbine jar file.')
|
|
parser.add_argument(
|
|
'--java-srcjars',
|
|
action='append',
|
|
default=[],
|
|
help='List of srcjars to include in compilation.')
|
|
parser.add_argument('--classpath', action='append', help='Classpath to use.')
|
|
parser.add_argument(
|
|
'--processors',
|
|
action='append',
|
|
help='GN list of annotation processor main classes.')
|
|
parser.add_argument(
|
|
'--processorpath',
|
|
action='append',
|
|
help='GN list of jars that comprise the classpath used for Annotation '
|
|
'Processors.')
|
|
parser.add_argument(
|
|
'--processor-args',
|
|
action='append',
|
|
help='key=value arguments for the annotation processors.')
|
|
parser.add_argument('--jar-path', help='Jar output path.', required=True)
|
|
parser.add_argument(
|
|
'--generated-jar-path',
|
|
required=True,
|
|
help='Output path for generated source files.')
|
|
parser.add_argument('--warnings-as-errors',
|
|
action='store_true',
|
|
help='Treat all warnings as errors.')
|
|
parser.add_argument('--kotlin-jar-path',
|
|
help='Kotlin jar to be merged into the output jar.')
|
|
options, unknown_args = parser.parse_known_args(argv)
|
|
|
|
options.classpath = action_helpers.parse_gn_list(options.classpath)
|
|
options.processorpath = action_helpers.parse_gn_list(options.processorpath)
|
|
options.processors = action_helpers.parse_gn_list(options.processors)
|
|
options.java_srcjars = action_helpers.parse_gn_list(options.java_srcjars)
|
|
|
|
files = []
|
|
for arg in unknown_args:
|
|
# Interpret a path prefixed with @ as a file containing a list of sources.
|
|
if arg.startswith('@'):
|
|
files.extend(build_utils.ReadSourcesList(arg[1:]))
|
|
|
|
# The target's .sources file contains both Java and Kotlin files. We use
|
|
# compile_kt.py to compile the Kotlin files to .class and header jars.
|
|
# Turbine is run only on .java files.
|
|
java_files = [f for f in files if f.endswith('.java')]
|
|
|
|
cmd = build_utils.JavaCmd() + [
|
|
'-classpath', options.turbine_jar_path, 'com.google.turbine.main.Main'
|
|
]
|
|
javac_cmd = [
|
|
# We currently target JDK 11 everywhere.
|
|
'--release',
|
|
'11',
|
|
]
|
|
|
|
# Turbine reads lists from command line args by consuming args until one
|
|
# starts with double dash (--). Thus command line args should be grouped
|
|
# together and passed in together.
|
|
if options.processors:
|
|
cmd += ['--processors']
|
|
cmd += options.processors
|
|
|
|
if options.processorpath:
|
|
cmd += ['--processorpath']
|
|
cmd += options.processorpath
|
|
|
|
if options.processor_args:
|
|
for arg in options.processor_args:
|
|
javac_cmd.extend(['-A%s' % arg])
|
|
|
|
if options.classpath:
|
|
cmd += ['--classpath']
|
|
cmd += options.classpath
|
|
|
|
if options.java_srcjars:
|
|
cmd += ['--source_jars']
|
|
cmd += options.java_srcjars
|
|
|
|
if java_files:
|
|
# Use jar_path to ensure paths are relative (needed for goma).
|
|
files_rsp_path = options.jar_path + '.java_files_list.txt'
|
|
with open(files_rsp_path, 'w') as f:
|
|
f.write(' '.join(java_files))
|
|
# Pass source paths as response files to avoid extremely long command
|
|
# lines that are tedius to debug.
|
|
cmd += ['--sources']
|
|
cmd += ['@' + files_rsp_path]
|
|
|
|
cmd += ['--javacopts']
|
|
cmd += javac_cmd
|
|
cmd += ['--'] # Terminate javacopts
|
|
|
|
# Use AtomicOutput so that output timestamps are not updated when outputs
|
|
# are not changed.
|
|
with action_helpers.atomic_output(options.jar_path) as output_jar, \
|
|
action_helpers.atomic_output(options.generated_jar_path) as gensrc_jar:
|
|
cmd += ['--output', output_jar.name, '--gensrc_output', gensrc_jar.name]
|
|
process_javac_output_partial = functools.partial(
|
|
ProcessJavacOutput, target_name=options.target_name)
|
|
|
|
logging.debug('Command: %s', cmd)
|
|
start = time.time()
|
|
try:
|
|
build_utils.CheckOutput(cmd,
|
|
print_stdout=True,
|
|
stdout_filter=process_javac_output_partial,
|
|
stderr_filter=process_javac_output_partial,
|
|
fail_on_output=options.warnings_as_errors)
|
|
except build_utils.CalledProcessError as e:
|
|
# Do not output stacktrace as it takes up space on gerrit UI, forcing
|
|
# you to click though to find the actual compilation error. It's never
|
|
# interesting to see the Python stacktrace for a Java compilation error.
|
|
sys.stderr.write(e.output)
|
|
sys.exit(1)
|
|
end = time.time() - start
|
|
logging.info('Header compilation took %ss', end)
|
|
if options.kotlin_jar_path:
|
|
with zipfile.ZipFile(output_jar.name, 'a') as out_zip:
|
|
path_transform = lambda p: p if p.endswith('.class') else None
|
|
zip_helpers.merge_zips(out_zip, [options.kotlin_jar_path],
|
|
path_transform=path_transform)
|
|
|
|
if options.depfile:
|
|
# GN already knows of the java files, so avoid listing individual java files
|
|
# in the depfile.
|
|
depfile_deps = (options.classpath + options.processorpath +
|
|
options.java_srcjars)
|
|
action_helpers.write_depfile(options.depfile, options.jar_path,
|
|
depfile_deps)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|