| # Bazel Kotlin Rules |
| |
| [](https://buildkite.com/bazel/kotlin-postsubmit) |
| <a href="https://github.com/bazelbuild/rules_kotlin/tree/master"><img src="https://img.shields.io/badge/Main%20Branch-master-blue.svg"/></a> |
| ### Releases |
| |
| <a href="https://github.com/bazelbuild/rules_kotlin/releases/latest"><img src="https://img.shields.io/github/v/release/bazelbuild/rules_kotlin?display_name=tag&label=Latest%20Stable%20Release"/></a> |
| <br/> |
| <a href="https://github.com/bazelbuild/rules_kotlin/releases/"><img src="https://img.shields.io/github/v/release/bazelbuild/rules_kotlin?display_name=tag&include_prereleases&label=Latest%20Release%20Candidate"/></a> |
| |
| For more information about release and changelogs please see [Changelog](CHANGELOG.md) or refer to the [Github Releases](https://github.com/bazelbuild/rules_kotlin/releases) page. |
| |
| # `rules_kotlin` Bazel Compatibility |
| - HEAD: `5`, `6` |
| - [Release 1.7](https://github.com/bazelbuild/rules_kotlin/releases/tag/v1.7.1): `4`, `5`, `6` |
| |
| # Overview |
| |
| **rules_kotlin** supports the basic paradigm of `*_binary`, `*_library`, `*_test` of other Bazel |
| language rules. It also supports `jvm`, `android`, and `js` flavors, with the prefix `kt_jvm` |
| and `kt_js`, and `kt_android` typically applied to the rules. |
| |
| Support for kotlin's -Xfriend-paths via the `associates=` attribute in the jvm allow access to |
| `internal` members. |
| |
| Also, `kt_jvm_*` rules support the following standard `java_*` rules attributes: |
| * `data` |
| * `resource_jars` |
| * `runtime_deps` |
| * `resources` |
| * `resources_strip_prefix` |
| * `exports` |
| |
| Android rules also support custom_package for `R.java` generation, `manifest=`, `resource_files`, etc. |
| |
| Other features: |
| * Persistent worker support. |
| * Mixed-Mode compilation (compile Java and Kotlin in one pass). |
| * Configurable Kotlinc distribution and version |
| * Configurable Toolchain |
| * Support for all recent major Kotlin releases. |
| |
| Javascript is reported to work, but is not as well maintained (at present) |
| |
| # Documentation |
| |
| Generated API documentation is available at |
| [https://bazelbuild.github.io/rules_kotlin/kotlin](https://bazelbuild.github.io/rules_kotlin/kotlin). |
| |
| # Quick Guide |
| |
| ## `WORKSPACE` |
| In the project's `WORKSPACE`, declare the external repository and initialize the toolchains, like |
| this: |
| |
| ```python |
| load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| |
| rules_kotlin_version = "1.9.0" |
| rules_kotlin_sha = "5766f1e599acf551aa56f49dab9ab9108269b03c557496c54acaf41f98e2b8d6" |
| http_archive( |
| name = "rules_kotlin", |
| urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v%s/rules_kotlin-v%s.tar.gz" % (rules_kotlin_version, rules_kotlin_version)], |
| sha256 = rules_kotlin_sha, |
| ) |
| |
| load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") |
| kotlin_repositories() # if you want the default. Otherwise see custom kotlinc distribution below |
| |
| load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") |
| kt_register_toolchains() # to use the default toolchain, otherwise see toolchains below |
| ``` |
| |
| ## `BUILD` files |
| |
| In your project's `BUILD` files, load the Kotlin rules and use them like so: |
| |
| ```python |
| load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") |
| |
| kt_jvm_library( |
| name = "package_name", |
| srcs = glob(["*.kt"]), |
| deps = [ |
| "//path/to/dependency", |
| ], |
| ) |
| ``` |
| |
| ## Custom toolchain |
| |
| To enable a custom toolchain (to configure language level, etc.) |
| do the following. In a `<workspace>/BUILD.bazel` file define the following: |
| |
| ```python |
| load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain") |
| |
| define_kt_toolchain( |
| name = "kotlin_toolchain", |
| api_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", "1.7", "1.8", or "1.9" |
| jvm_target = JAVA_LANGUAGE_LEVEL, # "1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17", "18", "19", "20" or "21" |
| language_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", "1.7", "1.8", or "1.9" |
| ) |
| ``` |
| |
| and then in your `WORKSPACE` file, instead of `kt_register_toolchains()` do |
| |
| ```python |
| register_toolchains("//:kotlin_toolchain") |
| ``` |
| |
| ## Custom `kotlinc` distribution (and version) |
| |
| To choose a different `kotlinc` distribution (1.3 and 1.4 variants supported), do the following |
| in your `WORKSPACE` file (or import from a `.bzl` file: |
| |
| ```python |
| load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") |
| |
| kotlin_repositories( |
| compiler_release = kotlinc_version( |
| release = "1.6.21", # just the numeric version |
| sha256 = "632166fed89f3f430482f5aa07f2e20b923b72ef688c8f5a7df3aa1502c6d8ba" |
| ) |
| ) |
| ``` |
| |
| ## Third party dependencies |
| _(e.g. Maven artifacts)_ |
| |
| Third party (external) artifacts can be brought in with systems such as [`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external) or [`bazel_maven_repository`](https://github.com/square/bazel_maven_repository) or [`bazel-deps`](https://github.com/johnynek/bazel-deps), but make sure the version you use doesn't naively use `java_import`, as this will cause bazel to make an interface-only (`ijar`), or ABI jar, and the native `ijar` tool does not know about kotlin metadata with respect to inlined functions, and will remove method bodies inappropriately. Recent versions of `rules_jvm_external` and `bazel_maven_repository` are known to work with Kotlin. |
| |
| # Development Setup Guide |
| As of 1.5.0, to use the rules directly from the rules_kotlin workspace (i.e. not the release artifact) |
| require the use of `release_archive` repository. This repository will build and configure the current |
| workspace to use `rules_kotlin` in the same manner as the released binary artifact. |
| |
| In the project's `WORKSPACE`, change the setup: |
| |
| ```python |
| |
| # Use local check-out of repo rules (or a commit-archive from github via http_archive or git_repository) |
| local_repository( |
| name = "rules_kotlin", |
| path = "../path/to/rules_kotlin_clone/", |
| ) |
| |
| load("@rules_kotlin//kotlin:dependencies.bzl", "kt_download_local_dev_dependencies") |
| |
| kt_download_local_dev_dependencies() |
| |
| load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "versions") |
| |
| kotlin_repositories() |
| |
| load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") |
| |
| kt_register_toolchains() |
| ``` |
| |
| To use rules_kotlin from head without cloning the repository, (caveat emptor, of course), change the |
| rules to this: |
| |
| ```python |
| # Download master or specific revisions |
| http_archive( |
| name = "rules_kotlin", |
| strip_prefix = "rules_kotlin-master", |
| urls = ["https://github.com/bazelbuild/rules_kotlin/archive/refs/heads/master.zip"], |
| ) |
| |
| load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") |
| |
| kotlin_repositories() |
| |
| load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") |
| |
| kt_register_toolchains() |
| ``` |
| |
| # Debugging native actions |
| |
| To attach debugger and step through native action code when using local checkout of rules_kotlin repo : |
| |
| 1. Open `rules_kotlin` project in Android Studio, using existing `.bazelproject` file as project view. |
| 2. In terminal, build the kotlin target you want to debug, using the subcommand option, ex: `bazel build //lib/mylib:main_kt -s`. You can also use `bazel aquery` to get this info. |
| 3. Locate the subcommand for the kotlin action you want to debug, let's say `KotlinCompile`. Note: If you don't see it, target rebuild may have been skipped (in this case `touch` one of the source .kt file to trigger rebuild). |
| 4. Export `REPOSITORY_NAME` as specified in action env, ex : `export REPOSITORY_NAME=rules_kotlin` |
| 5. Copy the command line, ex : `bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/rules_kotlin/src/main/kotlin/build '--flagfile=bazel-out/darwin_arm64-fastbuild/bin/lib/mylib/main_kt-kt.jar-0.params'` |
| 6. Change directory into the [execRoot](https://bazel.build/remote/output-directories#layout-diagram), normally `bazel-MYPROJECT`, available via `bazel info | grep execution_root`. |
| 7. Add `--debug=5005` to command line to make the action wait for a debugger to attach, ex: `bazel-out/darwin_arm64-opt-exec-2B5CBBC6/bin/external/rules_kotlin/src/main/kotlin/build --debug=5005 '--flagfile=bazel-out/darwin_arm64-fastbuild/bin/lib/mylib/main_kt-kt.jar-0.params'`. Note: if command invokes `java` toolchain directly, use `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005` instead. |
| 8. You should see in output that action is waiting for debugger. Use a default `Remote JVM Debug` configuration in Android Studio, set breakpoint in kotlin action java/kt code, and attach debugger. Breakpoints should be hit. |
| |
| # Kotlin and Java compiler flags |
| |
| The `kt_kotlinc_options` and `kt_javac_options` rules allows passing compiler flags to kotlinc and javac. |
| |
| Note: Not all compiler flags are supported in all language versions. When this happens, the rules will fail. |
| |
| For example you can define global compiler flags by doing: |
| ```python |
| load("@rules_kotlin//kotlin:core.bzl", "kt_kotlinc_options", "kt_javac_options", "define_kt_toolchain") |
| |
| kt_kotlinc_options( |
| name = "kt_kotlinc_options", |
| x_no_param_assertions = True, |
| jvm_target = "1.8", |
| ) |
| |
| kt_javac_options( |
| name = "kt_javac_options", |
| warn = "off", |
| ) |
| |
| define_kt_toolchain( |
| name = "kotlin_toolchain", |
| kotlinc_options = "//:kt_kotlinc_options", |
| javac_options = "//:kt_javac_options", |
| ) |
| ``` |
| |
| You can optionally override compiler flags at the target level by providing an alternative set of `kt_kotlinc_options` or `kt_javac_options` in your target definitions. |
| |
| Compiler flags that are passed to the rule definitions will be taken over the toolchain definition. |
| |
| Example: |
| ```python |
| load("@rules_kotlin//kotlin:core.bzl", "kt_kotlinc_options", "kt_javac_options") |
| load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") |
| |
| kt_kotlinc_options( |
| name = "kt_kotlinc_options_for_package_name", |
| x_no_param_assertions = True, |
| x_optin = [ |
| "kotlin.Experimental", |
| "kotlin.ExperimentalStdlibApi", |
| ], |
| ) |
| |
| kt_javac_options( |
| name = "kt_javac_options_for_package_name", |
| warn = "off" |
| ) |
| |
| kt_jvm_library( |
| name = "package_name", |
| srcs = glob(["*.kt"]), |
| kotlinc_opts = "//:kt_kotlinc_options_for_package_name", |
| javac_opts = "//:kt_javac_options_for_package_name", |
| deps = ["//path/to/dependency"], |
| ) |
| ``` |
| |
| Additionally, you can add options for both tracing and timing of the bazel build using the `kt_trace` and `kt_timings` flags, for example: |
| * `bazel build --define=kt_trace=1` |
| * `bazel build --define=kt_timings=1` |
| |
| `kt_trace=1` will allow you to inspect the full kotlinc commandline invocation, while `kt_timings=1` will report the high level time taken for each step. |
| |
| # KSP (Kotlin Symbol Processing) |
| |
| KSP is officially supported as of `rules_kotlin` 1.8 and can be declared using the new |
| `kt_ksp_plugin` rule. |
| |
| A few things to note: |
| - As of now `rules_kotlin` only supports KSP plugins that generate Kotlin code. |
| - KSP is [not yet thread safe](https://github.com/google/ksp/issues/1385) and will likely fail if you are using it in a build that has multiplex workers enabled. To work around this add the following flag to your Bazelrc: |
| ``` |
| build --experimental_worker_max_multiplex_instances=KotlinKsp=1 |
| ``` |
| |
| ```python |
| load("@rules_kotlin//kotlin:core.bzl", "kt_ksp_plugin") |
| load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") |
| |
| kt_ksp_plugin( |
| name = "moshi-kotlin-codegen", |
| processor_class = "com.squareup.moshi.kotlin.codegen.ksp.JsonClassSymbolProcessorProvider", |
| deps = [ |
| "@maven//:com_squareup_moshi_moshi", |
| "@maven//:com_squareup_moshi_moshi_kotlin", |
| "@maven//:com_squareup_moshi_moshi_kotlin_codegen", |
| ], |
| ) |
| |
| kt_jvm_library( |
| name = "lib", |
| srcs = glob(["*.kt"]), |
| plugins = ["//:moshi-kotlin-codegen"], |
| ) |
| ``` |
| |
| To choose a different `ksp_version` distribution, |
| do the following in your `WORKSPACE` file (or import from a `.bzl` file): |
| |
| ```python |
| load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "ksp_version") |
| |
| kotlin_repositories( |
| ksp_compiler_release = ksp_version( |
| release = "1.8.22-1.0.11", |
| sha256 = "2ce5a08fddd20ef07ac051615905453fe08c3ba3ce5afa5dc43a9b77aa64507d", |
| ), |
| ) |
| ``` |
| |
| # Kotlin compiler plugins |
| |
| The `kt_compiler_plugin` rule allows running Kotlin compiler plugins, such as no-arg, sam-with-receiver and allopen. |
| |
| For example, you can add allopen to your project like this: |
| ```python |
| load("@rules_kotlin//kotlin:core.bzl", "kt_compiler_plugin") |
| load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") |
| |
| kt_compiler_plugin( |
| name = "open_for_testing_plugin", |
| id = "org.jetbrains.kotlin.allopen", |
| options = { |
| "annotation": "plugin.allopen.OpenForTesting", |
| }, |
| deps = [ |
| "//kotlin/compiler:allopen-compiler-plugin", |
| ], |
| ) |
| |
| kt_jvm_library( |
| name = "user", |
| srcs = ["User.kt"], # The User class is annotated with OpenForTesting |
| plugins = [ |
| ":open_for_testing_plugin", |
| ], |
| deps = [ |
| ":open_for_testing", # This contains the annotation (plugin.allopen.OpenForTesting) |
| ], |
| ) |
| ``` |
| |
| Full examples of using compiler plugins can be found [here](examples/plugin). |
| |
| ## Examples |
| |
| Examples can be found in the [examples directory](https://github.com/bazelbuild/rules_kotlin/tree/master/examples), including usage with Android, Dagger, Node-JS, Kotlin compiler plugins, etc. |
| |
| # History |
| |
| These rules were initially forked from [pubref/rules_kotlin](http://github.com/pubref/rules_kotlin), and then re-forked from [bazelbuild/rules_kotlin](http://github.com/bazelbuild/rules_kotlin). They were merged back into this repository in October, 2019. |
| |
| # License |
| |
| This project is licensed under the [Apache 2.0 license](LICENSE), as are all contributions |
| |
| # Contributing |
| |
| See the [CONTRIBUTING](CONTRIBUTING.md) doc for information about how to contribute to |
| this project. |