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