Hi! I'm trying to update to Kotlin 2 and running i...
# ksp
j
Hi! I'm trying to update to Kotlin 2 and running into some issues with KSP and Arrow. I'm using the Optics plugin to generate some code using annotations. Here is my
build.gradle.kts
setup:
Copy code
plugins {
    alias(libs.plugins.kotlin.multiplatform)
    alias(libs.plugins.kotlin.native.cocoapods)
    alias(libs.plugins.android.library)
    alias(libs.plugins.skie)
    alias(libs.plugins.ksp)
}

kotlin {
  ...
   sourceSets {
        commonMain {
            kotlin.srcDir("build/generated/ksp/commonMain/kotlin")
            ...
         }
  }
}

dependencies {
    add("kspCommonMainMetadata", libs.arrow.opticsKspPlugin)
 
    configurations
        .filter { it.name.startsWith("ksp") && it.name != "ksp" }
        .forEach {
            add(it.name, libs.arrow.opticsKspPlugin)
        }
}

kotlin.sourceSets.commonMain {
    kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}
I'm noticing that when I build for Android, it generates the common code in
build/generated/ksp/android/androidDebug/kotlin/...
, instead of in a
commonMain
folder, and I end up with
unresolved reference
errors when I try to build. When I have Android Studio build just the
common
code, it generates it in the
commonMain
folder, but then I have an error about duplicate symbols. Do I need to change something with how KSP is set up in my config to support the new compiler? Versions: Kotlin 2.0.0, KSP 2.0.0-1.0.22, Arrow: 1.2.4.
j
can you check how many targets you are building? if you only build target is android then even if you have common source set, the build will still be a single build therefore no sources generated in common folder.
j
I am only building one target at a time...in this case Android... But shouldn't generated code for the common source set be in the
commonMain
folder? Otherwise, I'm going to have to somehow tell Gradle to look in other generated folders for that generated code which doesn't seem right to me. Also, if I remove the
kotlin.srcDir("build/generated/ksp/commonMain/kotlin")
line, it doesn't find anything.
After some spelunking in the Ktorfit gradle plugin, I discovered they were adding some task dependencies, as well as the generated source directory to the
commonMain
source set.
Copy code
kotlinExtension.sourceSets.named("commonMain").configure {   kotlin.srcDir("${layout.buildDirectory.get()}/generated/ksp/metadata/commonMain/kotlin")
}

tasks.withType(KotlinCompilationTask::class.java).configureEach {
    if (name != "kspCommonMainKotlinMetadata") {
        dependsOn("kspCommonMainKotlinMetadata")
    }
}
Adapting for my build.gradle.kts...
Copy code
kotlin.sourceSets.commonMain {
    kotlin.srcDir("${layout.buildDirectory.get()}/generated/ksp/metadata/commonMain/kotlin")
}

project.afterEvaluate {
    tasks.withType(KotlinCompilationTask::class.java).configureEach {
        if (name != "kspCommonMainKotlinMetadata") {
            dependsOn("kspCommonMainKotlinMetadata")
        }
}
It would be really nice if this were better documented somewhere.
j
This is caused by the behavior of KMP in general, rather than KSP specific behavior, which is the main reason we did not document it.
j
I suppose so. But there is some specific documentation on the kotlinlang.org site which talks about using KSP with KMP. This seems like a basic thing to document there. Not every KSP plugin provides its own Gradle plugin to do the necessary configuration.
j
sounds right, we will update the document to clear confusions.
❤️ 1
j
Thank you!