Skip to content

Latest commit

 

History

History
239 lines (177 loc) · 9.14 KB

File metadata and controls

239 lines (177 loc) · 9.14 KB

This document explains how to use Kotlin Symbol Processing (KSP) in a Kotlin Multiplatform project. To get started with Kotlin Multiplatform, see the Kotlin Multiplatform overview.

To use KSP-based processors in a multiplatform project, assign a processor to each target that needs symbol processing:

add("ksp<Target>", <processor>)

<processor> is a Gradle project path. It can be:

  • the specific folder in your project that contains the logic for your symbol processor.
  • an external processor such as Room or Dagger.

For a full list of targets, see Multiplatform Gradle DSL reference and Kotlin/Native supported targets.

{style=”tip”}

For example:

// build.gradle.kts

// This example demonstrates various ways to declare KSP dependencies
// in a Kotlin project, covering multiplatform setups.

plugins {
    // Apply the KSP plugin
    id("com.google.devtools.ksp") version "%kspVersion%"     
    // Apply other plugins as needed (e.g., kotlin("jvm"), 
    // kotlin("multiplatform"), etc.)
}

dependencies {
    // ===============================================================
    // 1. MAIN COMPILATIONS (Production Code)
    // ===============================================================

    // In KMP, the global 'ksp' configuration is deprecated to avoid running 
    // processors on targets unnecessarily. Use target-specific configurations instead.

    // Local processor for a specific target (JVM)
    add("kspJvm", project(":test-processor"))

    // External processor for a specific target (Android)
    add("kspAndroid", "androidx.room:room-compiler:2.6.1")

    // Target with multiple processors (JVM)
    add("kspJvm", project(":another-local-processor"))
    add("kspJvm", "com.example:external-processor:1.0")

    // Different processors for different targets
    add("kspJvm", project(":jvm-only-processor"))
    add("kspJs", project(":js-only-processor"))

    // iOS Targets
    // KSP configurations are per-compilation target. Shared intermediate 
    // source sets like 'iosMain' do NOT have their own KSP configuration.
    // You must specify them for each iOS target individually.
    add("kspIosX64", project(":test-processor"))
    add("kspIosArm64", project(":test-processor"))
    add("kspIosSimulatorArm64", project(":test-processor"))
    
    // TIP: If you have many iOS targets, you can avoid repetition by looping:
    kotlin.targets.filter { it.name.startsWith("ios") }.forEach { target ->
        add(
            "ksp${target.name.replaceFirstChar { it.uppercaseChar() }}",
            project(":test-processor")
        )
    }
    
    // ===============================================================
    // 2. TEST COMPILATIONS
    // ===============================================================

    // Specify KSP for the test compilation of each target:
    add("kspJvmTest", project(":test-processor"))
    add("kspJsTest", project(":test-processor"))
    add("kspIosX64Test", project(":test-processor"))


    // ===============================================================
    // 3. NEW ANDROID KOTLIN MULTIPLATFORM (Android-KMP)
    // Using id("com.android.kotlin.multiplatform.library")
    // ===============================================================
    
    // Main Android compilation (Target name is 'android')
    add("kspAndroid", project(":test-processor"))
    
    // Host Tests / Device Tests:
    // KSP generates these configurations dynamically based on the source set names.
    // The test source sets are named 'androidHostTest', 'androidDeviceTest', etc.
    
    add("kspAndroidHostTest", project(":test-processor"))
    add("kspAndroidDeviceTest", project(":test-processor"))
}
// build.gradle

// This example demonstrates various ways to declare KSP dependencies
// in a Kotlin project, covering multiplatform setups.

plugins {
    // Apply the KSP plugin
    id 'com.google.devtools.ksp' version '%kspVersion%'

    // Apply other plugins as needed (e.g., kotlin("jvm"),
    // kotlin("multiplatform"), etc.)
}

dependencies {
    // ===============================================================
    // 1. MAIN COMPILATIONS (Production Code)
    // ===============================================================

    // In KMP, the global 'ksp' configuration is deprecated to avoid running
    // processors on targets unnecessarily. Use target-specific configurations instead.

    // Local processor for a specific target (JVM)
    add('kspJvm', project(':test-processor'))

    // External processor for a specific target (Android)
    add('kspAndroid', 'androidx.room:room-compiler:2.6.1')

    // Target with multiple processors (JVM)
    add('kspJvm', project(':another-local-processor'))
    add('kspJvm', 'com.example:external-processor:1.0')

    // Different processors for different targets
    add('kspJvm', project(':jvm-only-processor'))
    add('kspJs', project(':js-only-processor'))

    // iOS Targets
    // KSP configurations are per-compilation target. Shared intermediate
    // source sets like 'iosMain' do NOT have their own KSP configuration.
    // You must specify them for each iOS target individually.
    add('kspIosX64', project(':test-processor'))
    add('kspIosArm64', project(':test-processor'))
    add('kspIosSimulatorArm64', project(':test-processor'))

    // TIP: If you have many iOS targets, you can avoid repetition by looping:
    kotlin.targets.findAll { it.name.startsWith('ios') }.each { target ->
        add("ksp${target.name.capitalize()}", project(':test-processor'))
    }

    // ===============================================================
    // 2. TEST COMPILATIONS
    // ===============================================================

    // Specify KSP for the test compilation of each target:
    add('kspJvmTest', project(':test-processor'))
    add('kspJsTest', project(':test-processor'))
    add('kspIosX64Test', project(':test-processor'))

    // ===============================================================
    // 3. NEW ANDROID KOTLIN MULTIPLATFORM (Android-KMP)
    // Using id("com.android.kotlin.multiplatform.library")
    // ===============================================================

    // Main Android compilation (Target name is 'android')
    add('kspAndroid', project(':test-processor'))

    // Host Tests / Device Tests:
    // KSP generates these configurations dynamically based on the source set names.
    // The test source sets are named 'androidHostTest', 'androidDeviceTest', etc.

    add('kspAndroidHostTest', project(':test-processor'))
    add('kspAndroidDeviceTest', project(':test-processor'))
}

Configuration names for tests in Multiplatform depend on the exact source set names generated by the Kotlin plugin. Run the following command in your terminal to see the definitive list of all generated KSP configurations for your module:

./gradlew :<your-module-name>:dependencies | grep ksp

Look for configurations matching your target names to find the right one.

Since KSP 2 the catch-all ksp(...) configuration has been deprecated. Although this may lead to some duplication in the build file, specifying each platform individually avoids the cost of applying target-specific processors to targets in which they do nothing.

To use the deprecated ksp(...) configuration, set the flag ksp.allow.all.target.configuration=true in gradle.properties.

{style=”tip”}

To see an example of a multiplatform project with several targets using KSP, visit the source repository.

Compilation and processing

In a multiplatform project, Kotlin creates a separate compilation for each target and source set, such as main and test. For every eligible Kotlin compilation task, KSP creates a corresponding symbol processing task.

The example project defines six targets:

  • JVM
  • JS
  • Linux X64
  • Android Native X64
  • Android Native Arm64
  • Mingw X64

Each of these targets includes a main and a test compilation. As a result, the project creates at least 12 Kotlin compilation tasks.

In the example's workload/build.gradle.kts, KSP dependencies are declared for the following configurations:

  • kspJvm and kspJvmTest
  • kspJs and kspJsTest
  • kspAndroidNativeX64 and kspAndroidNativeX64Test
  • kspAndroidNativeArm64 and kspAndroidNativeArm64Test
  • kspLinuxX64 (test is omitted/commented out)
  • kspMingwX64 (test is omitted/commented out)

KSP creates one symbol processing task for each configuration where a KSP dependency is declared. In this example, the project creates at least 12 Kotlin compilation tasks and 10 symbol processing tasks. The remaining compilations don't have corresponding KSP tasks because KSP isn't configured for them.