tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

turbine.py (6170B)


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