Hi all, is it possible to setup ksp to generate classes only for the MainMetadata? If I add `kspCom...
a
Hi all, is it possible to setup ksp to generate classes only for the MainMetadata? If I add
kspCommonMainMetadata
, it seems not to generate anything…
I basically will need to use a ksp processor to generate code like if I would be writing that code in
commonMain
, so no need of platform-specific code
j
under new KMP build model, if you do not specify more than 1 target platform, common task won’t be invoked.
a
I see, so does that mean it is not possible to generate common-only code?
a
It's possible. It probably does generate code for you but you need to manually add it as a source set
the following works for me: add in your commonMain source definition:
Copy code
val commonMain by getting {
    kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
and in the root of the build.gradle.kts
Copy code
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>>().all {
    if (name != "kspCommonMainKotlinMetadata") {
        dependsOn("kspCommonMainKotlinMetadata")
    }
}
that's with ksp 1.6.21-1.0.5
tested working with 1.7.21-1.0.8 too.
a
thanks, I’ll try the last task configuration; I had already the source configuration
m
my plugin looks like this:
Copy code
private const val TASK_NAME = "kspCommonMainKotlinMetadata"

class KSPPlugin : ProjectPlugin({
    apply(plugin = KSP_PLUGIN)

    tasks.withType<KotlinCompile<*>>().all {
        if (name != TASK_NAME) {
            dependsOn(TASK_NAME)
        }
    }

    configure<KotlinMultiplatformExtension> {
        sourceSets {
            commonMain {
                kotlin.srcDir("$buildDir/generated/ksp/metadata/commonMain/kotlin")
            }
        }
    }
})
It compiles and I am able to see the generated code from common (ie: autocomplete, etc). So it's 99% of the way there. But gradle complains:
Copy code
./gradlew clean build
Configuration on demand is an incubating feature.
Type-safe project accessors is an incubating feature.

> Task :modules:library:inject:api:jvmSourcesJar
Execution optimizations have been disabled for task ':modules:library:inject:api:jvmSourcesJar' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: '/home/marc/Code/modules/library/inject/api/build/generated/ksp/metadata/commonMain/kotlin'. Reason: Task ':modules:library:inject:api:jvmSourcesJar' uses this output of task ':modules:library:inject:api:kspCommonMainKotlinMetadata' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to <https://docs.gradle.org/7.6/userguide/validation_problems.html#implicit_dependency> for more details about this problem.

> Task :modules:library:inject:api:runKtlintCheckOverCommonMainSourceSet
Execution optimizations have been disabled for task ':modules:library:inject:api:runKtlintCheckOverCommonMainSourceSet' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: '/home/marc/Code/modules/library/inject/api/build/generated/ksp/metadata/commonMain/kotlin'. Reason: Task ':modules:library:inject:api:runKtlintCheckOverCommonMainSourceSet' uses this output of task ':modules:library:inject:api:kspCommonMainKotlinMetadata' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to <https://docs.gradle.org/7.6/userguide/validation_problems.html#implicit_dependency> for more details about this problem.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See <https://docs.gradle.org/7.6/userguide/command_line_interface.html#sec:command_line_warnings>

Execution optimizations have been disabled for 2 invalid unit(s) of work during this build to ensure correctness.
Please consult deprecation warnings for more details.

BUILD SUCCESSFUL in 1s
31 actionable tasks: 22 executed, 1 from cache, 8 up-to-date
a
It might be a problem that you can ignore for now https://kotlinlang.slack.com/archives/C013BA8EQSE/p1675418675704889 Gradle really likes to know what the inputs/outputs of tasks are, but it looks like some task isn’t properly registering the tasks inputs/outputs. It might be your task, or it might be a ktlint task. This simpler question&answer might help explain how to wire up Gradle tasks as sourceSet dirs: https://stackoverflow.com/questions/74743976/kotlin-multiplatform-accessing-build-variables-in-code
m
Thanks, makes sense. I am not sure how to apply it to my use case though because commonMain generates the code and the code needs to be seen by commonMain so we get a circular dependency.
Copy code
private const val TASK_NAME = "kspCommonMainKotlinMetadata"

class KSPPlugin : ProjectPlugin({
    apply(plugin = KSP_PLUGIN)

    val task = provider { tasks.named(TASK_NAME, KspTaskMetadata::class).get() }

    configure<KotlinMultiplatformExtension> {
        sourceSets {
            commonMain {
                val data = task.map { it.destinationDirectory }
                kotlin.srcDir(data)
            }
        }
    }
})
Copy code
* What went wrong:
Circular dependency between the following tasks:
:modules:shared:library:coroutines:core:kspCommonMainKotlinMetadata
\--- :modules:shared:library:coroutines:core:kspCommonMainKotlinMetadata (*)
239 Views