xref: /aosp_15_r20/build/bazel/rules/java/java_system_modules.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
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