1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 15*7594170eSAndroid Build Coastguard Worker 16*7594170eSAndroid Build Coastguard WorkerSystemInfo = provider(fields = ["system", "java_info"]) 17*7594170eSAndroid Build Coastguard Worker 18*7594170eSAndroid Build Coastguard Workerdef _gen_module_info_java(ctx, jars_to_module_info, jars, module_info): 19*7594170eSAndroid Build Coastguard Worker ctx.actions.run_shell( 20*7594170eSAndroid Build Coastguard Worker inputs = jars, 21*7594170eSAndroid Build Coastguard Worker outputs = [module_info], 22*7594170eSAndroid Build Coastguard Worker command = "{} java.base {} > {}".format( 23*7594170eSAndroid Build Coastguard Worker jars_to_module_info.path, 24*7594170eSAndroid Build Coastguard Worker " ".join([jar.path for jar in jars]), 25*7594170eSAndroid Build Coastguard Worker module_info.path, 26*7594170eSAndroid Build Coastguard Worker ), 27*7594170eSAndroid Build Coastguard Worker tools = [jars_to_module_info], 28*7594170eSAndroid Build Coastguard Worker ) 29*7594170eSAndroid Build Coastguard Worker 30*7594170eSAndroid Build Coastguard Workerdef _gen_module_info_class(ctx, java_runtime, module_info, java_base_patch_jars, module_info_class): 31*7594170eSAndroid Build Coastguard Worker ctx.actions.run_shell( 32*7594170eSAndroid Build Coastguard Worker inputs = depset([module_info], transitive = [java_base_patch_jars]), 33*7594170eSAndroid Build Coastguard Worker outputs = [module_info_class], 34*7594170eSAndroid Build Coastguard Worker tools = java_runtime.files, 35*7594170eSAndroid Build Coastguard Worker command = "{} -d {} --system=none --patch-module=java.base={} {}".format( 36*7594170eSAndroid Build Coastguard Worker paths.join(java_runtime.java_home, "bin", "javac"), 37*7594170eSAndroid Build Coastguard Worker module_info_class.dirname, 38*7594170eSAndroid Build Coastguard Worker ":".join([jar.path for jar in java_base_patch_jars.to_list()]), 39*7594170eSAndroid Build Coastguard Worker module_info.path, 40*7594170eSAndroid Build Coastguard Worker ), 41*7594170eSAndroid Build Coastguard Worker ) 42*7594170eSAndroid Build Coastguard Worker 43*7594170eSAndroid Build Coastguard Workerdef _gen_module_info_jar(ctx, soong_zip, module_info_class, module_info_jar): 44*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 45*7594170eSAndroid Build Coastguard Worker args.add("-jar") 46*7594170eSAndroid Build Coastguard Worker args.add("--symlinks=false") 47*7594170eSAndroid Build Coastguard Worker args.add("-o", module_info_jar) 48*7594170eSAndroid Build Coastguard Worker args.add("-C", module_info_class.dirname) 49*7594170eSAndroid Build Coastguard Worker args.add("-f", module_info_class) 50*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 51*7594170eSAndroid Build Coastguard Worker inputs = [module_info_class], 52*7594170eSAndroid Build Coastguard Worker outputs = [module_info_jar], 53*7594170eSAndroid Build Coastguard Worker arguments = [args], 54*7594170eSAndroid Build Coastguard Worker executable = soong_zip, 55*7594170eSAndroid Build Coastguard Worker ) 56*7594170eSAndroid Build Coastguard Worker 57*7594170eSAndroid Build Coastguard Workerdef _gen_merged_module_jar(ctx, merge_zips, module_info_jar, jars, merged_module_jar): 58*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 59*7594170eSAndroid Build Coastguard Worker args.add("-j", merged_module_jar) 60*7594170eSAndroid Build Coastguard Worker args.add_all(depset([module_info_jar], transitive = [jars])) 61*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 62*7594170eSAndroid Build Coastguard Worker inputs = depset([module_info_jar], transitive = [jars]), 63*7594170eSAndroid Build Coastguard Worker outputs = [merged_module_jar], 64*7594170eSAndroid Build Coastguard Worker arguments = [args], 65*7594170eSAndroid Build Coastguard Worker executable = merge_zips, 66*7594170eSAndroid Build Coastguard Worker ) 67*7594170eSAndroid Build Coastguard Worker 68*7594170eSAndroid Build Coastguard Workerdef _gen_jmod(ctx, java_runtime, merged_module_jar, jmod): 69*7594170eSAndroid Build Coastguard Worker ctx.actions.run_shell( 70*7594170eSAndroid Build Coastguard Worker inputs = [merged_module_jar], 71*7594170eSAndroid Build Coastguard Worker outputs = [jmod], 72*7594170eSAndroid Build Coastguard Worker tools = java_runtime.files, 73*7594170eSAndroid Build Coastguard Worker command = ( 74*7594170eSAndroid Build Coastguard Worker "{} create --module-version $({} --version) " + 75*7594170eSAndroid Build Coastguard Worker "--target-platform android --class-path {} {}" 76*7594170eSAndroid Build Coastguard Worker ).format( 77*7594170eSAndroid Build Coastguard Worker paths.join(java_runtime.java_home, "bin", "jmod"), 78*7594170eSAndroid Build Coastguard Worker paths.join(java_runtime.java_home, "bin", "jlink"), 79*7594170eSAndroid Build Coastguard Worker merged_module_jar.path, 80*7594170eSAndroid Build Coastguard Worker jmod.path, 81*7594170eSAndroid Build Coastguard Worker ), 82*7594170eSAndroid Build Coastguard Worker ) 83*7594170eSAndroid Build Coastguard Worker 84*7594170eSAndroid Build Coastguard Workerdef _gen_system(ctx, java_runtime, jmod, system): 85*7594170eSAndroid Build Coastguard Worker ctx.actions.run_shell( 86*7594170eSAndroid Build Coastguard Worker inputs = depset([jmod], transitive = [java_runtime.files]), 87*7594170eSAndroid Build Coastguard Worker outputs = [system], 88*7594170eSAndroid Build Coastguard Worker tools = java_runtime.files, 89*7594170eSAndroid Build Coastguard Worker command = ( 90*7594170eSAndroid Build Coastguard Worker "rm -rf {} && " + 91*7594170eSAndroid Build Coastguard Worker "{} --module-path {} --add-modules java.base --output {} " + 92*7594170eSAndroid Build Coastguard Worker "--disable-plugin system-modules && " + 93*7594170eSAndroid Build Coastguard Worker "cp {} {}/lib/" 94*7594170eSAndroid Build Coastguard Worker ).format( 95*7594170eSAndroid Build Coastguard Worker system.path, 96*7594170eSAndroid Build Coastguard Worker paths.join(java_runtime.java_home, "bin", "jlink"), 97*7594170eSAndroid Build Coastguard Worker jmod.dirname, 98*7594170eSAndroid Build Coastguard Worker system.path, 99*7594170eSAndroid Build Coastguard Worker paths.join(java_runtime.java_home, "lib", "jrt-fs.jar"), 100*7594170eSAndroid Build Coastguard Worker system.path, 101*7594170eSAndroid Build Coastguard Worker ), 102*7594170eSAndroid Build Coastguard Worker ) 103*7594170eSAndroid Build Coastguard Worker 104*7594170eSAndroid Build Coastguard Workerdef _java_system_modules_impl(ctx): 105*7594170eSAndroid Build Coastguard Worker java_info = java_common.merge([d[JavaInfo] for d in ctx.attr.deps]) 106*7594170eSAndroid Build Coastguard Worker module_info = ctx.actions.declare_file("%s/src/module-info.java" % ctx.label.name) 107*7594170eSAndroid Build Coastguard Worker _gen_module_info_java(ctx, ctx.executable._jars_to_module_info, java_info.compile_jars.to_list(), module_info) 108*7594170eSAndroid Build Coastguard Worker 109*7594170eSAndroid Build Coastguard Worker java_runtime = ctx.attr._runtime[java_common.JavaRuntimeInfo] 110*7594170eSAndroid Build Coastguard Worker module_info_class = ctx.actions.declare_file("%s/class/module-info.class" % ctx.label.name) 111*7594170eSAndroid Build Coastguard Worker _gen_module_info_class(ctx, java_runtime, module_info, java_info.compile_jars, module_info_class) 112*7594170eSAndroid Build Coastguard Worker 113*7594170eSAndroid Build Coastguard Worker module_info_jar = ctx.actions.declare_file("%s/jar/classes.jar" % ctx.label.name) 114*7594170eSAndroid Build Coastguard Worker _gen_module_info_jar(ctx, ctx.executable._soong_zip, module_info_class, module_info_jar) 115*7594170eSAndroid Build Coastguard Worker 116*7594170eSAndroid Build Coastguard Worker merged_module_jar = ctx.actions.declare_file("%s/merged/module.jar" % ctx.label.name) 117*7594170eSAndroid Build Coastguard Worker _gen_merged_module_jar( 118*7594170eSAndroid Build Coastguard Worker ctx, 119*7594170eSAndroid Build Coastguard Worker ctx.executable._merge_zips, 120*7594170eSAndroid Build Coastguard Worker module_info_jar, 121*7594170eSAndroid Build Coastguard Worker java_info.full_compile_jars, 122*7594170eSAndroid Build Coastguard Worker merged_module_jar, 123*7594170eSAndroid Build Coastguard Worker ) 124*7594170eSAndroid Build Coastguard Worker 125*7594170eSAndroid Build Coastguard Worker jmod = ctx.actions.declare_file("%s/jmod/java.base.jmod" % ctx.label.name) 126*7594170eSAndroid Build Coastguard Worker _gen_jmod(ctx, java_runtime, merged_module_jar, jmod) 127*7594170eSAndroid Build Coastguard Worker 128*7594170eSAndroid Build Coastguard Worker system = ctx.actions.declare_directory("%s/system" % ctx.label.name) 129*7594170eSAndroid Build Coastguard Worker _gen_system(ctx, java_runtime, jmod, system) 130*7594170eSAndroid Build Coastguard Worker 131*7594170eSAndroid Build Coastguard Worker return [ 132*7594170eSAndroid Build Coastguard Worker SystemInfo( 133*7594170eSAndroid Build Coastguard Worker system = system, 134*7594170eSAndroid Build Coastguard Worker java_info = java_info, 135*7594170eSAndroid Build Coastguard Worker ), 136*7594170eSAndroid Build Coastguard Worker DefaultInfo(files = depset([system])), 137*7594170eSAndroid Build Coastguard Worker ] 138*7594170eSAndroid Build Coastguard Worker 139*7594170eSAndroid Build Coastguard Workerjava_system_modules = rule( 140*7594170eSAndroid Build Coastguard Worker implementation = _java_system_modules_impl, 141*7594170eSAndroid Build Coastguard Worker attrs = { 142*7594170eSAndroid Build Coastguard Worker "_jars_to_module_info": attr.label( 143*7594170eSAndroid Build Coastguard Worker allow_files = True, 144*7594170eSAndroid Build Coastguard Worker executable = True, 145*7594170eSAndroid Build Coastguard Worker cfg = "exec", 146*7594170eSAndroid Build Coastguard Worker default = "//build/soong/scripts:jars-to-module-info-java", 147*7594170eSAndroid Build Coastguard Worker ), 148*7594170eSAndroid Build Coastguard Worker "_soong_zip": attr.label( 149*7594170eSAndroid Build Coastguard Worker cfg = "exec", 150*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 151*7594170eSAndroid Build Coastguard Worker doc = "The tool soong_zip", 152*7594170eSAndroid Build Coastguard Worker default = "//build/soong/zip/cmd:soong_zip", 153*7594170eSAndroid Build Coastguard Worker executable = True, 154*7594170eSAndroid Build Coastguard Worker ), 155*7594170eSAndroid Build Coastguard Worker "_merge_zips": attr.label( 156*7594170eSAndroid Build Coastguard Worker cfg = "exec", 157*7594170eSAndroid Build Coastguard Worker allow_single_file = True, 158*7594170eSAndroid Build Coastguard Worker doc = "The tool merge_zips.", 159*7594170eSAndroid Build Coastguard Worker default = "//build/soong/cmd/merge_zips", 160*7594170eSAndroid Build Coastguard Worker executable = True, 161*7594170eSAndroid Build Coastguard Worker ), 162*7594170eSAndroid Build Coastguard Worker "_runtime": attr.label( 163*7594170eSAndroid Build Coastguard Worker default = Label("@bazel_tools//tools/jdk:current_java_runtime"), 164*7594170eSAndroid Build Coastguard Worker cfg = "exec", 165*7594170eSAndroid Build Coastguard Worker providers = [java_common.JavaRuntimeInfo], 166*7594170eSAndroid Build Coastguard Worker ), 167*7594170eSAndroid Build Coastguard Worker "deps": attr.label_list( 168*7594170eSAndroid Build Coastguard Worker providers = [JavaInfo], 169*7594170eSAndroid Build Coastguard Worker doc = "Libraries to be converted into a system module directory structure.", 170*7594170eSAndroid Build Coastguard Worker ), 171*7594170eSAndroid Build Coastguard Worker }, 172*7594170eSAndroid Build Coastguard Worker doc = """Generates a system module directory from Java libraries. 173*7594170eSAndroid Build Coastguard Worker 174*7594170eSAndroid Build Coastguard WorkerStarting from version 1.9, Java requires a subset of java.* classes to be 175*7594170eSAndroid Build Coastguard Workerprovided via system modules. This rule encapsulates the set of steps necessary 176*7594170eSAndroid Build Coastguard Workerto convert a jar file into the directory structure of system modules. 177*7594170eSAndroid Build Coastguard Worker""", 178*7594170eSAndroid Build Coastguard Worker) 179