rules_kotlin

repository·master·Indexed 18 days ago

https://github.com/bazel-contrib/rules_kotlin

Bazel rules for compiling Kotlin code, supporting JVM, Android, and JS flavors. It features mixed-mode compilation for Java and Kotlin, custom toolchain configuration, and support for Kotlin Symbol Processing (KSP) via kt_ksp_plugin. The library provides rules like kt_jvm_library and kt_compiler_plugin, and supports performance optimizations including ABI jars for compilation avoidance, persistent/multiplex workers, and transitive dependency pruning.

Tokens
15.2K
Snippets
40
Records
58
Agent score
63%

What's inside rules_kotlin

  1. How resource path resolution works with resource_strip_prefix across module boundaries

    master

    When using resource_strip_prefix in a Kotlin target, rules_kotlin ensures that resource paths are correctly resolved even when the target depends on an external Bazel module.

    If a library in an external module (e.g., @nested//:library) defines resources with a specific resource_strip_prefix, the rules must correctly identify the resource path relative to that prefix, regardless of whether the external module's directory is included in .bazelignore or how the module path is prefixed in the filesystem.

    In a correctly functioning setup, a resource located at nested/resourcez/resource.txt with resource_strip_prefix = "resourcez" will be correctly stripped, allowing the application to access the resource via the path resource.txt.

  2. Add a new integration test to rules_kotlin

    master

    To add a new integration test to the rules_kotlin repository, follow these steps:

    1. Create a new workspace within the examples/ directory.
    2. Ensure the rules_kotlin repository is named exactly rules_kotlin in your configuration.
    3. If the example is incompatible with specific Bazel versions, create an exclude directory containing a file named after that Bazel version.
    4. Update the list of excluded packages by running the following command:
    bazel run @rules_bazel_integration_test//tools:update_deleted_packages
    bazel run @rules_bazel_integration_test//tools:update_deleted_packages
  3. Enable compilation avoidance via ABI jars

    master

    You can improve build performance by enabling compilation avoidance. This uses ABI jars (interface/header jars) for classpath dependencies, allowing Bazel to avoid recompiling downstream targets when changes do not affect the public API.

    To enable this, set experimental_use_abi_jars = True in your define_kt_toolchain configuration.

    load("//kotlin:core.bzl", "define_kt_toolchain")
    
    define_kt_toolchain(
        name = "kotlin_toolchain",
        experimental_use_abi_jars = True,
    )
  4. Configure and tune Kotlin workers

    master

    Kotlin compilation uses persistent and multiplex workers by default to improve performance. The following mnemonics support workers:

    • KotlinCompile: Main Kotlin compilation
    • KotlinKsp2: KSP 2 symbol processing
    • JdepsMerge: Jdeps file merging

    Disabling Workers

    To fall back to non-worker execution for a specific mnemonic, use the local strategy.

    Managing Multiplex Workers

    • Disable Multiplexing: Set the max multiplex instances to 0 for a mnemonic to use regular persistent workers instead.
    • Tuning Concurrency: Set the number of concurrent multiplex work units per worker process using experimental_worker_max_multiplex_instances.
    # Disable workers for specific mnemonics
    build --strategy=KotlinCompile=local
    build --strategy=KotlinKsp2=local
    build --strategy=JdepsMerge=local
    
    # Disable multiplex workers (use regular persistent workers)
    build --experimental_worker_max_multiplex_instances=KotlinCompile=0
    
    # Tune multiplex worker concurrency
    build --experimental_worker_max_multiplex_instances=KotlinCompile=5
  5. Install and launch the Jetpack Compose example app on Android

    master

    To install the Jetpack Compose example app onto an Android device and launch it immediately, use the bazel mobile-install command. You must specify the target, the Android platform architecture (e.g., --android_platforms=//:arm64-v8a), and use the -- separator to pass the --launch_activity flag to the device.

    bazel mobile-install //app:compose_example_app --android_platforms=//:arm64-v8a -- --launch_activity=cm.ben.android.bazel.compose.example.ui.MainActivity
  6. Enable Multiplex Sandboxing and Path Mapping

    master

    Multiplex sandboxing provides isolation for work requests within a multiplex worker. Path mapping rewrites action paths to shorter, config-independent forms to reduce cache misses when switching configurations.

    Note: Path mapping requires multiplex sandboxing to be enabled.

    To use these features, you must:

    1. Define a toolchain with experimental_multiplex_sandboxing and supports_path_mapping set to True using define_kt_toolchain.
    2. Register the toolchain in your WORKSPACE.
    3. Pass the required Bazel flags during build.
    load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain")
    
    define_kt_toolchain(
        name = "kotlin_toolchain",
        experimental_multiplex_sandboxing = True,
        supports_path_mapping = True,
    )
    # In WORKSPACE
    register_toolchains("//:kotlin_toolchain")
    # Activate features via CLI
    build --experimental_worker_multiplex_sandboxing
    build --experimental_output_paths=strip
  7. Install rules_kotlin via WORKSPACE

    master

    To use rules_kotlin with a WORKSPACE file, declare the http_archive for rules_kotlin, initialize the repositories using kotlin_repositories(), and register the toolchains using kt_register_toolchains().

    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
  8. Use KSP (Kotlin Symbol Processing) with kt_ksp_plugin

    master

    KSP is supported via the kt_ksp_plugin rule. You define a processor and then apply it to a kt_jvm_library via the plugins attribute.

    Configuring KSP Version

    You can specify a custom KSP version distribution depending on your dependency management system.

    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"],
    )
  9. Configure a custom Kotlin toolchain

    master

    To customize language levels and JVM targets, define a toolchain using define_kt_toolchain in a BUILD file, then register it in your WORKSPACE file.

    Supported API versions: 1.9, 2.0, 2.1, 2.2, or 2.3. Supported JVM targets: 1.8, 9 through 25.

    # In <workspace>/BUILD.bazel
    load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain")
    
    define_kt_toolchain(
        name = "kotlin_toolchain",
        api_version = KOTLIN_LANGUAGE_LEVEL,  # e.g., "1.9"
        jvm_target = JAVA_LANGUAGE_LEVEL, # e.g., "17"
        language_version = KOTLIN_LANGUAGE_LEVEL,  # e.g., "1.9"
    )
    
    # In WORKSPACE
    register_toolchains("//:kotlin_toolchain")
  10. Compile different library types in the dependencies example

    master

    The dependencies example contains a chain of libraries (lib1 -> lib2 -> lib3 -> lib4) supporting various language and platform combinations. Use the following commands to build specific library types:

    • Java JVM: Build a regular Java library for the JVM.
    • Java Android: Build a regular Java library for Android.
    • Kotlin JVM: Build a regular Kotlin library for the JVM.
    • Kotlin Android: Build a Kotlin library for Android (requires building both src_main and src_main_kt targets).
    # Regular Java JVM library
    bazel build libJava1:src_main
    
    # Regular Java Android library
    bazel build liblibAndroid1Java1:src_main
    
    # Regular Kotlin JVM library
    bazel build libKt1:src_main
    
    # Android Kotlin library
    bazel build libKtAndroid1:src_main libKtAndroid1:src_main_kt