12
votes

I have the following project structure

root-project
│   build.gradle.kts
│
└───multiplatform-project
│   │   build.gradle.kts 
│   │
│   └───src
│       │   kotlin
|       |   js
│   
└───simple-kotlin-project
    │   build.gradle.kts

So there are 3 projects in total (3 build.gradle.kts files).

  1. Here is the root project build.gradle.kts

    plugins {
        kotlin("jvm") version kotlinVersion apply false
        kotlin("kapt") version kotlinVersion apply false
        kotlin("multiplatform") version kotlinVersion apply false
    }
    
    subprojects {
        apply<JavaPlugin>()
    
        if (name.contains("multiplatform-project")) {
            apply(plugin = "org.jetbrains.kotlin.multiplatform")
        } else {
            apply(plugin = "kotlin")
        }
    
        apply(plugin = "kotlin-kapt")
    
        dependencies {
            implementation(kotlin("stdlib"))
            implementation(kotlin("reflect"))
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M2")
    
            implementation("org.slf4j:slf4j-api:1.7.25")
            implementation("ch.qos.logback:logback-core:1.2.3")
            implementation("ch.qos.logback:logback-classic:1.2.3")
    
            testImplementation("junit:junit:$jUnitVersion")
        }
    }
    
  2. Here is the simple kotlin project that uses kapt and that works

    val jacksonVersion: String by project
    
    dependencies {
        implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
        implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
        implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion")
        implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
    
        kapt(project(":generator")) // THIS WORKS!!!
    }
    
  3. Now my question is how to make this work in the multiplatorm project which looks like that

    val jacksonVersion: String by project
    val ktorVersion: String by project
    
    kotlin {
        jvm {
            val main by compilations.getting {
                kotlinOptions {
                    jvmTarget = JavaVersion.VERSION_1_8.toString()
                }
    
                compileKotlinTask
                output
            }
        }
        js {}
    
        sourceSets {
            val jvmMain by getting {
                dependencies {
                    implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
                    implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
                    implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion")
    
                    implementation("io.ktor:ktor-html-builder:$ktorVersion")
                    implementation("io.ktor:ktor-server-netty:$ktorVersion")
    
                    kapt(project(":generator")) // THIS DOESN'T WORK!!!
                }
            }
        }
    }
    

Here is the error that I see in IDEA

enter image description here

That is not a phantom error. If I run gradle build, I get the following error:

build.gradle.kts:38:22: Type mismatch: inferred type is ProjectDependency but Action was expected

So, the question boils down to how do I run kapt plugin on the kotlin sourceSet the same way that I can do it in a simple kotlin project by adding it to dependencies of the project.

2

2 Answers

10
votes

I think you've already found the answer your looking for, but let me post it here for any other users that might be interested in working around the issue.

The issue is mainly caused by kapt resolving to the Project extension registered under the kapt name by the Kotlin Gradle Plugin. Because of this, the extension to declare a dependency in the kapt Configuration isn't available in the kotlin.sourceSets.jvm().compilations["main"].defaultSourceSet.dependencies scope.

The workaround consist in manually getting the configuration and adding the project dependency to it:

sourceSets {
    val jvmMain by getting {
      dependencies {
        ...
        configurations.get("kapt").dependencies.add(project(":generator"))
      }
    }
}
0
votes

For anyone looking to add a kapt dependency, for example, android's hilt-compiler, to the androidMain sourceSet you can:

sourceSets {
    val androidMain by getting {
        dependencies {
            // declare the implementation for the compiler
            implementation("com.google.dagger:hilt-compiler:2.37")

            // configure kapt to utilize
            configurations.getByName("kapt").dependencies.add(
                DefaultExternalModuleDependency(
                    "com.google.dagger",
                    "hilt-compiler",
                    "2.37"
                )
            )
        }
    }
}