| # Copyright 2018 The Bazel Authors. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Kotlin Rules |
| |
| ### Setup |
| |
| Add the following snippet to your `WORKSPACE` file: |
| |
| ```bzl |
| git_repository( |
| name = "io_bazel_rules_kotlin", |
| remote = "https://github.com/bazelbuild/rules_kotlin.git", |
| commit = "<COMMIT_HASH>", |
| ) |
| load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains") |
| kotlin_repositories(kotlin_release_version = "1.2.21") |
| kt_register_toolchains() |
| ``` |
| |
| To enable persistent worker support, add the following to the appropriate `bazelrc` file: |
| |
| ``` |
| build --strategy=KotlinCompile=worker |
| test --strategy=KotlinCompile=worker |
| ``` |
| |
| |
| ### Standard Libraries |
| |
| The Kotlin libraries that are bundled in a kotlin release should be used with the rules, the mandatory standard libraries are added implicetly. After enabling |
| the repository the following Kotlin Libraries are also made available from the workspace `com_github_jetbrains_kotlin`: |
| |
| * `kotlin-test`, |
| * `kotlin-reflect`. |
| |
| So if you needed to add reflect as a dep use the following label `@com_github_jetbrains_kotlin//:kotlin-reflect`. |
| |
| ### Mixed Mode compilation |
| |
| The JVM rules can compile both Java and Kotlin sources. The Java compiler wrapper is not optimized or persistent and does not have the features found in the |
| native java rules. This mode is usefull for migrating a package to Kotlin over time. |
| |
| ### Annotation Processing |
| |
| Annotation processing works just as it does in Java, plugins are declared via a [`java_plugin`](https://docs.bazel.build/versions/master/be/java.html#java_plugin) |
| and may also be inherited from a `java_library` via the `exported_plugins` attribute. Annotation work in mixed-mode compilation and the Kotlin compiler take |
| care of processing both aspects. |
| |
| An example which can be found under `//examples/dagger`: |
| |
| ```bzl |
| java_plugin( |
| name = "dagger_plugin", |
| deps = [ |
| "@dagger_compiler//jar", |
| "@guava//jar", |
| "@dagger_producers//jar", |
| "@dagger//jar", |
| "@javax_inject//jar" |
| ], |
| processor_class = "dagger.internal.codegen.ComponentProcessor" |
| ) |
| |
| java_library( |
| name = "dagger_lib", |
| exports = [ |
| "@javax_inject//jar", |
| "@dagger//jar", |
| ], |
| exported_plugins = ["dagger_plugin"] |
| ) |
| |
| kt_jvm_binary( |
| name = "dagger", |
| srcs = glob(["src/**"]), |
| main_class = "coffee.CoffeeApp", |
| deps = [":dagger_lib"], |
| ) |
| ``` |
| """ |
| |
| load( |
| "//kotlin/internal:defs.bzl", |
| _KtJvmInfo = "KtJvmInfo", |
| _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE", |
| ) |
| load( |
| "//kotlin/internal/jvm:plugins.bzl", |
| _kt_jvm_plugin_aspect = "kt_jvm_plugin_aspect", |
| ) |
| load( |
| "//kotlin/internal:defs.bzl", |
| _KT_COMPILER_REPO = "KT_COMPILER_REPO", |
| ) |
| load( |
| "//kotlin/internal/jvm:impl.bzl", |
| _kt_jvm_binary_impl = "kt_jvm_binary_impl", |
| _kt_jvm_import_impl = "kt_jvm_import_impl", |
| _kt_jvm_junit_test_impl = "kt_jvm_junit_test_impl", |
| _kt_jvm_library_impl = "kt_jvm_library_impl", |
| ) |
| |
| _implicit_deps = { |
| "_singlejar": attr.label( |
| executable = True, |
| cfg = "host", |
| default = Label("@bazel_tools//tools/jdk:singlejar"), |
| allow_files = True, |
| ), |
| "_zipper": attr.label( |
| executable = True, |
| cfg = "host", |
| default = Label("@bazel_tools//tools/zip:zipper"), |
| allow_files = True, |
| ), |
| "_java": attr.label( |
| executable = True, |
| cfg = "host", |
| default = Label("@bazel_tools//tools/jdk:java"), |
| allow_files = True, |
| ), |
| "_java_stub_template": attr.label( |
| cfg = "host", |
| default = Label("@kt_java_stub_template//file"), |
| ), |
| "_toolchain": attr.label( |
| doc = """The Kotlin JVM Runtime. it's only purpose is to enable the Android native rules to discover the Kotlin |
| runtime for dexing""", |
| default = Label("@" + _KT_COMPILER_REPO + "//:kotlin-runtime"), |
| cfg = "target", |
| ), |
| } |
| |
| _common_attr = _implicit_deps + { |
| "srcs": attr.label_list( |
| doc = """The list of source files that are processed to create the target, this can contain both Java and Kotlin |
| files. Java analysis occurs first so Kotlin classes may depend on Java classes in the same compilation unit.""", |
| default = [], |
| allow_files = [".srcjar", ".kt", ".java"], |
| ), |
| "deps": attr.label_list( |
| doc = """A list of dependencies of this rule.See general comments about `deps` at |
| [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).""", |
| aspects = [_kt_jvm_plugin_aspect], |
| providers = [ |
| [JavaInfo], |
| ], |
| allow_files = False, |
| ), |
| "runtime_deps": attr.label_list( |
| doc = """Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will |
| appear on the runtime classpath, but unlike them, not on the compile-time classpath.""", |
| default = [], |
| allow_files = False, |
| ), |
| "resources": attr.label_list( |
| doc = """A list of files that should be include in a Java jar.""", |
| default = [], |
| allow_files = True, |
| ), |
| "resource_strip_prefix": attr.string( |
| doc = """The path prefix to strip from Java resources, files residing under common prefix such as |
| `src/main/resources` or `src/test/resources` will have stripping applied by convention.""", |
| default = "", |
| ), |
| "resource_jars": attr.label_list( |
| doc = """Set of archives containing Java resources. If specified, the contents of these jars are merged into |
| the output jar.""", |
| default = [], |
| ), |
| "data": attr.label_list( |
| doc = """The list of files needed by this rule at runtime. See general comments about `data` at |
| [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).""", |
| allow_files = True, |
| cfg = "data", |
| ), |
| "plugins": attr.label_list( |
| default = [], |
| aspects = [_kt_jvm_plugin_aspect], |
| ), |
| "module_name": attr.string( |
| doc = """The name of the module, if not provided the module name is derived from the label. --e.g., |
| `//some/package/path:label_name` is translated to |
| `some_package_path-label_name`.""", |
| mandatory = False, |
| ), |
| } |
| |
| _lib_common_attr = _common_attr + { |
| "exports": attr.label_list( |
| doc = """Exported libraries. |
| |
| Deps listed here will be made available to other rules, as if the parents explicitly depended on |
| these deps. This is not true for regular (non-exported) deps.""", |
| default = [], |
| providers = [JavaInfo], |
| ), |
| "neverlink": attr.bool( |
| doc = """If true only use this library for compilation and not at runtime.""", |
| default = False, |
| ), |
| } |
| |
| _runnable_common_attr = _common_attr + { |
| "jvm_flags": attr.string_list( |
| doc = """A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet |
| support make variable substitution.""", |
| default = [], |
| ), |
| } |
| |
| _common_outputs = dict( |
| jar = "%{name}.jar", |
| jdeps = "%{name}.jdeps", |
| # The params file, declared here so that validate it can be validated for testing. |
| # jar_2_params = "%{name}.jar-2.params", |
| srcjar = "%{name}-sources.jar", |
| ) |
| |
| kt_jvm_library = rule( |
| doc = """This rule compiles and links Kotlin and Java sources into a .jar file.""", |
| attrs = _lib_common_attr, |
| outputs = _common_outputs, |
| toolchains = [_TOOLCHAIN_TYPE], |
| implementation = _kt_jvm_library_impl, |
| provides = [JavaInfo, _KtJvmInfo], |
| ) |
| |
| kt_jvm_binary = rule( |
| doc = """Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. The wrapper |
| shell script uses a classpath that includes, among other things, a jar file for each library on which the binary |
| depends. |
| |
| **Note:** This rule does not have all of the features found in [`java_binary`](https://docs.bazel.build/versions/master/be/java.html#java_binary). |
| It is appropriate for building workspace utilities. `java_binary` should be preferred for release artefacts. |
| """, |
| attrs = dict(_runnable_common_attr.items() + { |
| "main_class": attr.string( |
| doc = """Name of class with main() method to use as entry point.""", |
| mandatory = True, |
| ), |
| }.items()), |
| executable = True, |
| outputs = _common_outputs, |
| toolchains = [_TOOLCHAIN_TYPE], |
| implementation = _kt_jvm_binary_impl, |
| ) |
| |
| kt_jvm_test = rule( |
| doc = """Setup a simple kotlin_test. |
| |
| **Notes:** |
| * The kotlin test library is not added implicitly, it is available with the label |
| `@com_github_jetbrains_kotlin//:kotlin-test`. |
| """, |
| attrs = _runnable_common_attr + { |
| "_bazel_test_runner": attr.label( |
| default = Label("@bazel_tools//tools/jdk:TestRunner_deploy.jar"), |
| allow_files = True, |
| ), |
| "friends": attr.label_list( |
| doc = """A single Kotlin dep which allows the test code access to internal members. Currently uses the output |
| jar of the module -- i.e., exported deps won't be included.""", |
| default = [], |
| providers = [JavaInfo, _KtJvmInfo], |
| ), |
| "test_class": attr.string( |
| doc = "The Java class to be loaded by the test runner.", |
| default = "", |
| ), |
| "main_class": attr.string(default = "com.google.testing.junit.runner.BazelTestRunner"), |
| }, |
| executable = True, |
| outputs = _common_outputs, |
| test = True, |
| toolchains = [_TOOLCHAIN_TYPE], |
| implementation = _kt_jvm_junit_test_impl, |
| ) |
| |
| kt_jvm_import = rule( |
| doc = """Import Kotlin jars. |
| |
| ## examples |
| |
| ```bzl |
| # Old style usage -- reference file groups, do not used this. |
| kt_jvm_import( |
| name = "kodein", |
| jars = [ |
| "@com_github_salomonbrys_kodein_kodein//jar:file", |
| "@com_github_salomonbrys_kodein_kodein_core//jar:file" |
| ] |
| ) |
| |
| # This style will pull in the transitive runtime dependencies of the targets as well. |
| kt_jvm_import( |
| name = "kodein", |
| jars = [ |
| "@com_github_salomonbrys_kodein_kodein//jar", |
| "@com_github_salomonbrys_kodein_kodein_core//jar" |
| ] |
| ) |
| |
| # Import a single kotlin jar. |
| kt_jvm_import( |
| name = "kotlin-runtime", |
| jars = ["lib/kotlin-runtime.jar"], |
| srcjar = "lib/kotlin-runtime-sources.jar" |
| ) |
| ``` |
| """, |
| attrs = { |
| "jars": attr.label_list( |
| doc = """The jars listed here are equavalent to an export attribute. The label should be either to a single |
| class jar, or multiple filegroup labels. When the labels is a file_provider it should follow the conventions |
| used in repositories generated by the maven_jar rule --i.e., the rule expects a file_provider with a single |
| class jar and a single source jar. a source jar is recognized by the suffix `-sources.jar`.""", |
| allow_files = True, |
| mandatory = True, |
| cfg = "target", |
| ), |
| "srcjar": attr.label( |
| doc = """The sources for the class jar. This should generally be provided especially when importing a single |
| jar.""", |
| allow_single_file = True, |
| cfg = "target", |
| ), |
| "runtime_deps": attr.label_list( |
| doc = """Additional runtime deps.""", |
| default = [], |
| mandatory = False, |
| providers = [JavaInfo], |
| ), |
| }, |
| implementation = _kt_jvm_import_impl, |
| provides = [JavaInfo, _KtJvmInfo], |
| ) |