Search code examples
kotlingradlebuild.gradlekotlin-gradle-plugin

How to generate Kotlin code in Gradle based on non-generated code, finally packing both into output jar?


I have some Kotlin code in a library Gradle project, and I want to generate some additional Kotlin code using introspection on the original code (so that has to be compiled first). The process is started by a main() function in the original code. Then, the newly generated code should also get compiled, and both compiled outputs should together go into the output jar.

I have this, so far:

sourceSets {
    generated {
        kotlin {
            srcDir "src/generated/kotlin"
        }
        compileClasspath += main.output + configurations.runtimeClasspath
        runtimeClasspath += main.output
    }
}

task generateCode(type: JavaExec) {
    classpath = sourceSets.main.runtimeClasspath
    mainClass = "com.something.CodeGenMainKt"
    doFirst {
        file("src/generated/kotlin").mkdirs()
    }

    dependsOn compileKotlin
}

task compileGeneratedKotlin(type: KotlinCompile) {
    source = sourceSets.generated.kotlin
    dependsOn generateCode
}


jar {
    dependsOn compileGeneratedKotlin
    from sourceSets.main.output
    from sourceSets.generated.output
}

But get this error:

A problem occurred evaluating root project 'biz-kotlin'.
> Could not create task ':compileGeneratedKotlin'.
   > Could not create task of type 'KotlinCompile'.
      > Unable to determine constructor argument #1: missing parameter of type KotlinJvmCompilerOptions, or no service of type KotlinJvmCompilerOptions.

Why can't I / how can I add the additional compilation step? And does the rest of the script look ok?


Solution

  • As per this comment, we need to use kotlin.target.compilations.create to create a custom kotlin compile task. Keeping the rest of your build.gradle as is, the compileGeneratedKotlin task implemented like the below works for me.

    kotlin.target.compilations.create("compileGeneratedKotlin") { it ->
        it.source(sourceSets.generated)
    }
    tasks['compileGeneratedKotlin'].dependsOn(generateCode)
    

    With this, the test kotlin file I generated gets compiled and included in the generated jar file.