xref: /aosp_15_r20/external/bazelbuild-kotlin-rules/kotlin/jvm_compile.bzl (revision 3a22c0a33dd99bcca39a024d43e6fbcc55c2806e)
1# Copyright 2022 Google LLC. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the License);
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Compile method that can compile kotlin or java sources"""
16
17load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN")
18load("//bazel:stubs.bzl", "lint_actions")
19load(":common.bzl", "common")
20load(":compiler_plugin.bzl", "KtCompilerPluginInfo")
21load(":traverse_exports.bzl", "kt_traverse_exports")
22
23visibility(RULES_DEFS_THAT_COMPILE_KOTLIN)
24
25_RULE_FAMILY = common.RULE_FAMILY
26
27def kt_jvm_compile(
28        ctx,
29        output,
30        srcs,
31        common_srcs,
32        deps,
33        plugins,
34        runtime_deps,
35        exports,
36        javacopts,
37        kotlincopts,
38        neverlink,
39        testonly,
40        android_lint_plugins,
41        resource_files,
42        exported_plugins,
43        java_android_lint_config = None,
44        manifest = None,
45        merged_manifest = None,
46        classpath_resources = [],
47        kt_toolchain = None,
48        java_toolchain = None,
49        android_lint_rules_jars = depset(),
50        disable_lint_checks = [],
51        r_java = None,
52        output_srcjar = None,
53        rule_family = _RULE_FAMILY.UNKNOWN,
54        annotation_processor_additional_outputs = [],
55        annotation_processor_additional_inputs = [],
56        coverage_srcs = [],
57        **_kwargs):
58    """
59    The Kotlin JVM Compile method.
60
61    Args:
62      ctx: The context.
63      output: A File. The output jar.
64      srcs: List of Files. The Kotlin and Java sources.
65      common_srcs: List of common source files.
66      deps: List of targets. A list of dependencies.
67      plugins: List of targets. A list of jvm plugins.
68      runtime_deps: List of targets. A list of runtime deps.
69      exports: List of targets. A list of exports.
70      javacopts: List of strings. A list of Java compile options.
71      kotlincopts: List of strings. A list of Kotlin compile options.
72      neverlink: A bool. Signifies whether the target is only used for compile-time.
73      testonly: A bool. Signifies whether the target is only used for testing only.
74      android_lint_plugins: List of targets. An list of android lint plugins to
75        execute as a part of linting.
76      resource_files: List of Files. The list of Android Resource files.
77      exported_plugins: List of exported javac/kotlinc plugins
78      java_android_lint_config: Android Lint XML config file to use if there are no Kotlin srcs
79      manifest: A File. The raw Android manifest. Optional.
80      merged_manifest: A File. The merged Android manifest. Optional.
81      classpath_resources: List of Files. The list of classpath resources (kt_jvm_library only).
82      kt_toolchain: The Kotlin toolchain.
83      java_toolchain: The Java toolchain.
84      android_lint_rules_jars: Depset of Files. Standalone Android Lint rule Jar artifacts.
85      disable_lint_checks: Whether to disable link checks.
86        NOTE: This field should only be used when the provider is not produced
87        by a target. For example, the JavaInfo created for the Android R.java
88        within an android_library rule.
89      r_java: A JavaInfo provider. The JavaInfo provider for the Android R.java
90        which is both depended on and propagated as an export.
91        NOTE: This field accepts a JavaInfo, but should only be used for the
92        Android R.java within an android_library rule.
93      output_srcjar: Target output file for generated source jar. Default filename used if None.
94      rule_family: The family of the rule calling this function. Element of common.RULE_FAMILY.
95        May be used to enable/disable some features.
96      annotation_processor_additional_outputs: sequence of Files. A list of
97        files produced by an annotation processor.
98      annotation_processor_additional_inputs: sequence of Files. A list of
99        files consumed by an annotation processor.
100      coverage_srcs: Files to use as the basis when computing code coverage. These are typically
101        handwritten files that were inputs to generated `srcs`. Should be disjoint with `srcs`.
102      **_kwargs: Unused kwargs so that parameters are easy to add and remove.
103
104    Returns:
105      A struct that carries the following fields: java_info and validations.
106    """
107    if rule_family != _RULE_FAMILY.ANDROID_LIBRARY and not (srcs + common_srcs + exports):
108        # Demands either of the following to be present.
109        # - Source-type artifacts, srcs or common_srcs, including an empty
110        #   tree-artifact (a directory) or a srcjar without jar entries.
111        # - Exporting targets, exports. It is typically used by a library author
112        #   to publish one user-facing target with direct exposure to its
113        # dependent libraries.
114        fail("Expected one of (srcs, common_srcs, exports) is not empty for kotlin/jvm_compile on target: {}".format(ctx.label))
115
116    if classpath_resources and rule_family != _RULE_FAMILY.JVM_LIBRARY:
117        fail("resources attribute only allowed for jvm libraries")
118
119    if type(java_toolchain) == "Target":
120        # Allow passing either a target or a provider until all callers are updated
121        java_toolchain = java_toolchain[java_common.JavaToolchainInfo]
122
123    java_infos = []
124
125    # The r_java field only support Android resources Jar files. For now, verify
126    # that the name of the jar matches "_resources.jar". This check does not to
127    # prevent malicious use, the intent is to prevent accidental usage.
128    r_java_infos = []
129    if r_java:
130        for jar in r_java.outputs.jars:
131            if not jar.class_jar.path.endswith("_resources.jar"):
132                fail("Error, illegal dependency provided for r_java. This " +
133                     "only supports Android resource Jar files, " +
134                     "'*_resources.jar'.")
135        r_java_infos.append(r_java)
136
137    # Skip deps validation check for any android_library target with no kotlin sources: b/239721906
138    has_kt_srcs = any([common.is_kt_src(src) for src in srcs])
139    if rule_family != _RULE_FAMILY.ANDROID_LIBRARY or has_kt_srcs:
140        kt_traverse_exports.expand_forbidden_deps(deps + runtime_deps + exports)
141
142    for dep in deps:
143        if JavaInfo in dep:
144            java_infos.append(dep[JavaInfo])
145        else:
146            fail("Unexpected dependency (must provide JavaInfo): %s" % dep.label)
147
148    if kotlincopts != None and "-Werror" in kotlincopts:
149        fail("Flag -Werror is not permitted")
150
151    return common.kt_jvm_library(
152        ctx,
153        classpath_resources = classpath_resources,
154        common_srcs = common_srcs,
155        coverage_srcs = coverage_srcs,
156                deps = r_java_infos + java_infos,
157        disable_lint_checks = disable_lint_checks,
158        exported_plugins = common.kt_plugins_map(
159            java_plugin_infos = common.collect_providers(JavaPluginInfo, exported_plugins),
160            android_lint_rulesets = common.collect_providers(lint_actions.AndroidLintRulesetInfo, exported_plugins),
161        ),
162        # Not all exported targets contain a JavaInfo (e.g. some only have CcInfo)
163        exports = r_java_infos + [e[JavaInfo] for e in exports if JavaInfo in e],
164        friend_jars = kt_traverse_exports.expand_friend_jars(deps, root = ctx),
165        java_toolchain = java_toolchain,
166        javacopts = javacopts,
167        kotlincopts = kotlincopts,
168        compile_jdeps = kt_traverse_exports.expand_direct_jdeps(deps),
169        kt_toolchain = kt_toolchain,
170        manifest = manifest,
171        merged_manifest = merged_manifest,
172        native_libraries = [p[CcInfo] for p in deps + runtime_deps + exports if CcInfo in p],
173        neverlink = neverlink,
174        output = output,
175        output_srcjar = output_srcjar,
176        plugins = common.kt_plugins_map(
177            android_lint_rulesets = (
178                common.collect_providers(lint_actions.AndroidLintRulesetInfo, android_lint_plugins) +
179                common.collect_providers(lint_actions.AndroidLintRulesetInfo, plugins)
180            ) + [
181                lint_actions.AndroidLintRulesetInfo(singlejars = android_lint_rules_jars),
182            ],
183            java_plugin_infos = common.collect_providers(JavaPluginInfo, plugins),
184            kt_compiler_plugin_infos = (
185                kt_traverse_exports.expand_compiler_plugins(deps).to_list() +
186                common.collect_providers(KtCompilerPluginInfo, plugins)
187            ),
188        ),
189        java_android_lint_config = java_android_lint_config,
190        resource_files = resource_files,
191        runtime_deps = [d[JavaInfo] for d in runtime_deps if JavaInfo in d],
192        srcs = srcs,
193        testonly = testonly,
194        rule_family = rule_family,
195        annotation_processor_additional_outputs = annotation_processor_additional_outputs,
196        annotation_processor_additional_inputs = annotation_processor_additional_inputs,
197    )
198