tor-browser

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

compile_kt.py (6221B)


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