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