xref: /aosp_15_r20/external/bazelbuild-kotlin-rules/kotlin/jvm_library.internal.bzl (revision 3a22c0a33dd99bcca39a024d43e6fbcc55c2806e)
1*3a22c0a3SAlix# Copyright 2022 Google LLC. All rights reserved.
2*3a22c0a3SAlix#
3*3a22c0a3SAlix# Licensed under the Apache License, Version 2.0 (the License);
4*3a22c0a3SAlix# you may not use this file except in compliance with the License.
5*3a22c0a3SAlix# You may obtain a copy of the License at
6*3a22c0a3SAlix#
7*3a22c0a3SAlix#     http://www.apache.org/licenses/LICENSE-2.0
8*3a22c0a3SAlix#
9*3a22c0a3SAlix# Unless required by applicable law or agreed to in writing, software
10*3a22c0a3SAlix# distributed under the License is distributed on an "AS IS" BASIS,
11*3a22c0a3SAlix# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*3a22c0a3SAlix# See the License for the specific language governing permissions and
13*3a22c0a3SAlix# limitations under the License.
14*3a22c0a3SAlix
15*3a22c0a3SAlix"""Kotlin kt_jvm_library rule."""
16*3a22c0a3SAlix
17*3a22c0a3SAlixload("//kotlin:compiler_opt.bzl", "kotlincopts_attrs", "merge_kotlincopts")
18*3a22c0a3SAlixload("//toolchains/kotlin_jvm:androidlint_toolchains.bzl", "androidlint_toolchains")
19*3a22c0a3SAlixload("//toolchains/kotlin_jvm:java_toolchains.bzl", "java_toolchains")
20*3a22c0a3SAlixload("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
21*3a22c0a3SAlixload("@bazel_skylib//lib:dicts.bzl", "dicts")
22*3a22c0a3SAlixload("//bazel:stubs.bzl", "lint_actions")
23*3a22c0a3SAlixload(":common.bzl", "common")
24*3a22c0a3SAlixload(":compiler_plugin.bzl", "KtCompilerPluginInfo")
25*3a22c0a3SAlixload(":traverse_exports.bzl", "kt_traverse_exports")
26*3a22c0a3SAlixload(":jvm_compile.bzl", "kt_jvm_compile")
27*3a22c0a3SAlix
28*3a22c0a3SAlix# TODO: Use this function in all Kotlin rules
29*3a22c0a3SAlixdef _make_default_info(ctx, direct_files, propagated_attrs):
30*3a22c0a3SAlix    # Collect runfiles from deps
31*3a22c0a3SAlix    transitive_runfiles = []
32*3a22c0a3SAlix    for p in common.collect_providers(DefaultInfo, propagated_attrs):
33*3a22c0a3SAlix        transitive_runfiles.append(p.data_runfiles.files)
34*3a22c0a3SAlix        transitive_runfiles.append(p.default_runfiles.files)
35*3a22c0a3SAlix    runfiles = ctx.runfiles(
36*3a22c0a3SAlix        files = direct_files,
37*3a22c0a3SAlix        transitive_files = depset(transitive = transitive_runfiles),
38*3a22c0a3SAlix        collect_default = True,  # handles data attribute
39*3a22c0a3SAlix    )
40*3a22c0a3SAlix
41*3a22c0a3SAlix    return DefaultInfo(
42*3a22c0a3SAlix        files = depset(direct_files),
43*3a22c0a3SAlix        runfiles = runfiles,
44*3a22c0a3SAlix    )
45*3a22c0a3SAlix
46*3a22c0a3SAlixdef _jvm_library_impl(ctx):
47*3a22c0a3SAlix    kt_jvm_toolchain = kt_jvm_toolchains.get(ctx)
48*3a22c0a3SAlix
49*3a22c0a3SAlix    for target in ctx.attr.runtime_deps:
50*3a22c0a3SAlix        if (JavaInfo not in target) and (CcInfo not in target):
51*3a22c0a3SAlix            fail("Unexpected runtime dependency (must provide JavaInfo or CcInfo): " + str(target.label))
52*3a22c0a3SAlix
53*3a22c0a3SAlix    if not ctx.files.srcs and not ctx.files.common_srcs and not ctx.attr.exports and not ctx.attr.exported_plugins:
54*3a22c0a3SAlix        fail("Expected a source-bearing or an export-oriented target:\n" +
55*3a22c0a3SAlix             "One of {srcs, common_srcs, exports, exported_plugins} of target %s must be non empty" % ctx.label)
56*3a22c0a3SAlix
57*3a22c0a3SAlix    compile_result = kt_jvm_compile(
58*3a22c0a3SAlix        ctx,
59*3a22c0a3SAlix        output = ctx.outputs.jar,
60*3a22c0a3SAlix        srcs = ctx.files.srcs,
61*3a22c0a3SAlix        common_srcs = ctx.files.common_srcs,
62*3a22c0a3SAlix        deps = ctx.attr.deps,
63*3a22c0a3SAlix        plugins = ctx.attr.plugins,
64*3a22c0a3SAlix        exported_plugins = ctx.attr.exported_plugins,
65*3a22c0a3SAlix        runtime_deps = ctx.attr.runtime_deps,
66*3a22c0a3SAlix        exports = ctx.attr.exports,
67*3a22c0a3SAlix        javacopts = ctx.attr.javacopts,
68*3a22c0a3SAlix        kotlincopts = merge_kotlincopts(ctx),
69*3a22c0a3SAlix        neverlink = ctx.attr.neverlink,
70*3a22c0a3SAlix        testonly = ctx.attr.testonly,
71*3a22c0a3SAlix                android_lint_plugins = ctx.attr._android_lint_plugins,
72*3a22c0a3SAlix        manifest = None,
73*3a22c0a3SAlix        merged_manifest = None,
74*3a22c0a3SAlix        resource_files = [],
75*3a22c0a3SAlix        classpath_resources = ctx.files.resources,
76*3a22c0a3SAlix        kt_toolchain = kt_jvm_toolchain,
77*3a22c0a3SAlix        java_toolchain = java_toolchains.get(ctx),
78*3a22c0a3SAlix        disable_lint_checks = ctx.attr.disable_lint_checks,
79*3a22c0a3SAlix        rule_family = common.RULE_FAMILY.JVM_LIBRARY,
80*3a22c0a3SAlix    )
81*3a22c0a3SAlix
82*3a22c0a3SAlix    java_info = compile_result.java_info
83*3a22c0a3SAlix
84*3a22c0a3SAlix    # Collect and validate proguard_specs
85*3a22c0a3SAlix    # TODO should also propagate IDL proguard_specs when there's idl_srcs
86*3a22c0a3SAlix    transitive_proguard_configs = common.collect_proguard_specs(
87*3a22c0a3SAlix        ctx,
88*3a22c0a3SAlix        ctx.files.proguard_specs,
89*3a22c0a3SAlix        ctx.attr.deps + ctx.attr.exports,
90*3a22c0a3SAlix        kt_jvm_toolchain.proguard_whitelister,
91*3a22c0a3SAlix    )
92*3a22c0a3SAlix
93*3a22c0a3SAlix    # Create OutputGroupInfo
94*3a22c0a3SAlix    output_groups = dict(
95*3a22c0a3SAlix        _validation = depset(compile_result.validations),
96*3a22c0a3SAlix        _source_jars = depset(
97*3a22c0a3SAlix            java_info.source_jars,
98*3a22c0a3SAlix            transitive = [java_info.transitive_source_jars],
99*3a22c0a3SAlix        ),
100*3a22c0a3SAlix        _direct_source_jars = depset(java_info.source_jars),
101*3a22c0a3SAlix        _hidden_top_level_INTERNAL_ = depset(
102*3a22c0a3SAlix            transitive = [
103*3a22c0a3SAlix                info._hidden_top_level_INTERNAL_
104*3a22c0a3SAlix                for info in common.collect_providers(
105*3a22c0a3SAlix                    OutputGroupInfo,
106*3a22c0a3SAlix                    ctx.attr.deps + ctx.attr.exports,
107*3a22c0a3SAlix                )
108*3a22c0a3SAlix            ] + [transitive_proguard_configs],
109*3a22c0a3SAlix        ),
110*3a22c0a3SAlix    )
111*3a22c0a3SAlix
112*3a22c0a3SAlix    return [
113*3a22c0a3SAlix        java_info,
114*3a22c0a3SAlix        ProguardSpecProvider(transitive_proguard_configs),
115*3a22c0a3SAlix        _make_default_info(
116*3a22c0a3SAlix            ctx,
117*3a22c0a3SAlix            [ctx.outputs.jar],
118*3a22c0a3SAlix            propagated_attrs = ctx.attr.deps + ctx.attr.runtime_deps + ctx.attr.exports,
119*3a22c0a3SAlix        ),
120*3a22c0a3SAlix        OutputGroupInfo(**output_groups),
121*3a22c0a3SAlix        coverage_common.instrumented_files_info(
122*3a22c0a3SAlix            ctx,
123*3a22c0a3SAlix            source_attributes = ["srcs", "common_srcs"],
124*3a22c0a3SAlix            dependency_attributes = ["data", "deps", "resources", "runtime_deps"],
125*3a22c0a3SAlix        ),
126*3a22c0a3SAlix    ]
127*3a22c0a3SAlix
128*3a22c0a3SAlix_KT_JVM_LIBRARY_ATTRS = dicts.add(
129*3a22c0a3SAlix    androidlint_toolchains.attrs,
130*3a22c0a3SAlix    java_toolchains.attrs,
131*3a22c0a3SAlix    kotlincopts_attrs(),
132*3a22c0a3SAlix    kt_jvm_toolchains.attrs,
133*3a22c0a3SAlix    common_srcs = attr.label_list(
134*3a22c0a3SAlix        allow_files = common.KT_FILE_TYPES,
135*3a22c0a3SAlix        allow_empty = True,
136*3a22c0a3SAlix        doc = """The list of common multi-platform source files that are processed to create
137*3a22c0a3SAlix                 the target.""",
138*3a22c0a3SAlix    ),
139*3a22c0a3SAlix    data = attr.label_list(
140*3a22c0a3SAlix        allow_files = True,
141*3a22c0a3SAlix    ),
142*3a22c0a3SAlix    deps = attr.label_list(
143*3a22c0a3SAlix        providers = [
144*3a22c0a3SAlix            # Each provider-set expands on allow_rules
145*3a22c0a3SAlix            [JavaInfo],
146*3a22c0a3SAlix        ],
147*3a22c0a3SAlix        aspects = [
148*3a22c0a3SAlix            kt_traverse_exports.aspect,
149*3a22c0a3SAlix        ],
150*3a22c0a3SAlix        doc = """The list of libraries this library directly depends on at compile-time. For Java
151*3a22c0a3SAlix                     and Kotlin libraries listed, the Jars they build as well as the transitive closure
152*3a22c0a3SAlix                     of their `deps` and `exports` will be on the compile-time classpath for this rule;
153*3a22c0a3SAlix                     also, the transitive closure of their `deps`, `runtime_deps`, and `exports` will be
154*3a22c0a3SAlix                     on the runtime classpath (excluding dependencies only depended on as `neverlink`).
155*3a22c0a3SAlix
156*3a22c0a3SAlix                     Note on strict_deps: any Java type explicitly or implicitly referred to in `srcs`
157*3a22c0a3SAlix                     must be included here. This is a stronger requirement than what is enforced for
158*3a22c0a3SAlix                     `java_library`. Any build failures resulting from this requirement will include the
159*3a22c0a3SAlix                     missing dependencies and a command to fix the rule.""",
160*3a22c0a3SAlix    ),
161*3a22c0a3SAlix    disable_lint_checks = attr.string_list(
162*3a22c0a3SAlix        doc = """A list of lint checks to be skipped for this target.""",
163*3a22c0a3SAlix    ),
164*3a22c0a3SAlix    exported_plugins = attr.label_list(
165*3a22c0a3SAlix        providers = [
166*3a22c0a3SAlix            [JavaPluginInfo],
167*3a22c0a3SAlix            [KtCompilerPluginInfo],
168*3a22c0a3SAlix            [lint_actions.AndroidLintRulesetInfo],
169*3a22c0a3SAlix        ],
170*3a22c0a3SAlix        cfg = "exec",
171*3a22c0a3SAlix        doc = """JVM plugins to export to users.
172*3a22c0a3SAlix
173*3a22c0a3SAlix                     Every plugin listed will run during compliations that depend on this target, as
174*3a22c0a3SAlix                     if it were listed directly in that target's `plugins` attribute. `java_*` targets
175*3a22c0a3SAlix                     will not run kotlinc plugins""",
176*3a22c0a3SAlix    ),
177*3a22c0a3SAlix    exports = attr.label_list(
178*3a22c0a3SAlix        providers = [
179*3a22c0a3SAlix            # Each provider-set expands on allow_rules
180*3a22c0a3SAlix            [JavaInfo],
181*3a22c0a3SAlix        ],
182*3a22c0a3SAlix        aspects = [
183*3a22c0a3SAlix            kt_traverse_exports.aspect,
184*3a22c0a3SAlix        ],
185*3a22c0a3SAlix        doc = """List of libraries treated as if they were part of this library by upstream
186*3a22c0a3SAlix                     Java/Kotlin dependencies, see go/be-java#java_library.exports. These libraries
187*3a22c0a3SAlix                     are **not** automatically also dependencies of this library.""",
188*3a22c0a3SAlix    ),
189*3a22c0a3SAlix    javacopts = attr.string_list(
190*3a22c0a3SAlix        doc = """Additional flags to pass to javac if used as part of this rule, which is the case
191*3a22c0a3SAlix                     if `.java` `srcs` are provided or annotation processors generate sources for this
192*3a22c0a3SAlix                     rule.""",
193*3a22c0a3SAlix    ),
194*3a22c0a3SAlix    neverlink = attr.bool(
195*3a22c0a3SAlix        default = False,
196*3a22c0a3SAlix        doc = """Only use this library for compilation and not at runtime. Useful if the library
197*3a22c0a3SAlix                  will be provided by the runtime environment during execution.""",
198*3a22c0a3SAlix    ),
199*3a22c0a3SAlix    plugins = attr.label_list(
200*3a22c0a3SAlix        providers = [
201*3a22c0a3SAlix            [JavaPluginInfo],
202*3a22c0a3SAlix            [KtCompilerPluginInfo],
203*3a22c0a3SAlix            [lint_actions.AndroidLintRulesetInfo],
204*3a22c0a3SAlix        ],
205*3a22c0a3SAlix        cfg = "exec",
206*3a22c0a3SAlix        doc = """JVM plugins to run during compilation.
207*3a22c0a3SAlix
208*3a22c0a3SAlix                     Every plugin listed will run whenever this library is built. Resources generated by the
209*3a22c0a3SAlix                     plugin will be included in the output JAR. A library may also inherit plugins from
210*3a22c0a3SAlix                     dependencies that use `exported_plugins`.""",
211*3a22c0a3SAlix    ),
212*3a22c0a3SAlix    proguard_specs = attr.label_list(
213*3a22c0a3SAlix        allow_files = True,
214*3a22c0a3SAlix        doc = """Proguard specifications to go along with this library.""",
215*3a22c0a3SAlix    ),
216*3a22c0a3SAlix    resources = attr.label_list(
217*3a22c0a3SAlix        allow_files = True,
218*3a22c0a3SAlix        doc = """A list of data files to include in the Jar, see
219*3a22c0a3SAlix                         go/be#java_library.resources.""",
220*3a22c0a3SAlix    ),
221*3a22c0a3SAlix    runtime_deps = attr.label_list(
222*3a22c0a3SAlix        providers = [
223*3a22c0a3SAlix            # Each provider-set expands on allow_rules
224*3a22c0a3SAlix            [JavaInfo],
225*3a22c0a3SAlix            [CcInfo],  # for JNI / native dependencies
226*3a22c0a3SAlix        ],
227*3a22c0a3SAlix        aspects = [
228*3a22c0a3SAlix            kt_traverse_exports.aspect,
229*3a22c0a3SAlix        ],
230*3a22c0a3SAlix        doc = """Runtime-only dependencies.""",
231*3a22c0a3SAlix    ),
232*3a22c0a3SAlix    srcs = attr.label_list(
233*3a22c0a3SAlix        allow_files = common.KT_JVM_FILE_TYPES,
234*3a22c0a3SAlix        allow_empty = True,
235*3a22c0a3SAlix        doc = """The list of source files that are processed to create the target.
236*3a22c0a3SAlix                 To support circular dependencies, this can include `.kt` and `.java` files.""",
237*3a22c0a3SAlix    ),
238*3a22c0a3SAlix    _android_lint_plugins = attr.label_list(
239*3a22c0a3SAlix        providers = [lint_actions.AndroidLintRulesetInfo],
240*3a22c0a3SAlix        cfg = "exec",
241*3a22c0a3SAlix        doc = """Additional Android Lint checks to run at compile-time.""",
242*3a22c0a3SAlix    ),
243*3a22c0a3SAlix)
244*3a22c0a3SAlix
245*3a22c0a3SAlixkt_jvm_library_helper = rule(
246*3a22c0a3SAlix    attrs = _KT_JVM_LIBRARY_ATTRS,
247*3a22c0a3SAlix    fragments = ["java"],
248*3a22c0a3SAlix    outputs = dict(
249*3a22c0a3SAlix        jar = "lib%{name}.jar",
250*3a22c0a3SAlix        srcjar = "lib%{name}-src.jar",  # implicit declared output for consistency with java_library
251*3a22c0a3SAlix    ),
252*3a22c0a3SAlix    provides = [JavaInfo],
253*3a22c0a3SAlix    implementation = _jvm_library_impl,
254*3a22c0a3SAlix    toolchains = [kt_jvm_toolchains.type, "@bazel_tools//tools/jdk:toolchain_type"],
255*3a22c0a3SAlix    doc = """This rule compiles Kotlin (and Java) sources into a Jar file. Most Java-like libraries
256*3a22c0a3SAlix             and binaries can depend on this rule, and this rule can in turn depend on Kotlin and
257*3a22c0a3SAlix             Java libraries. This rule supports a subset of attributes supported by `java_library`.
258*3a22c0a3SAlix             In addition to documentation provided as part of this rule, please also refer to their
259*3a22c0a3SAlix             documentation as part of `java_library`.""",
260*3a22c0a3SAlix)
261