google / ksp

Kotlin Symbol Processing API

Home Page:https://github.com/google/ksp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IDE not indexing generated source

davidjwiner opened this issue · comments

Looks like that kapt has an IDE plugin to achieve this: KaptProjectResolverExtension.kt

We either need to copy it over, or simply tell users to mark generated source root themselves in the preview.

For now, I've manually supported this like so

sourceSets {
  main {
    java {
      srcDir(file("build/generated/ksp/src/main"))
    }
  }
  test {
    java {
      srcDir(file("build/generated/ksp/src/test"))
    }
  }
}

The IDE extension, where KaptProjectResolverExtension resides, is bundled with the IntelliJ Kotlin plugin. Therefore that approach doesn't work for now.

Moving this to Q4 as it depends on upstreaming, which won't happen in Q3.

Deferring again to 2021Q1.

buildTypes {
    getByName("debug") {
        sourceSets {
            getByName("main") {
                java.srcDir(File("build/generated/ksp/debug/kotlin"))
            }
        }
    }
    getByName("release") {
        sourceSets {
            getByName("main") {
                java.srcDir(File("build/generated/ksp/release/kotlin"))
            }
        }

    }
}

I am using above script in build.gradle.kts and working as well for now.

As a slight modification to the above, here's an approach that's a little more compact and flexible (for Android projects):

    applicationVariants.all {
        val variantName = name
        sourceSets {
            getByName("main") {
                java.srcDir(File("build/generated/ksp/$variantName/kotlin"))
            }
        }
    }

We use this logic in our tooling:

        plugins.withId("com.google.devtools.ksp") {
            the<BaseExtension>().variants.configureEach {
                addJavaSourceFoldersToModel(layout.buildDirectory
                    .dir("generated/ksp/$name/kotlin").get().asFile)
            }
        }

having:

val BaseExtension.variants: DomainObjectSet<out BaseVariant>
    get() = when (this) {
        is AppExtension -> applicationVariants
        is LibraryExtension -> libraryVariants
        is TestExtension -> applicationVariants
        else -> error("unsupported module type: $this")
    }

For android folks who want to set kotlin sourceSets, we can configure it this way

android.applicationVariants.all { variant ->
    kotlin.sourceSets {
        def name = variant.name
        getByName(name) {
            kotlin.srcDir("build/generated/ksp/$name/kotlin")
        }
    }
}

This worked for us in an android library module.

androidComponents.onVariants {variant ->
    kotlin.sourceSets.findByName(variant.name)?.kotlin?.srcDirs(
        file("$buildDir/generated/ksp/${variant.name}/kotlin")
    )
}

I'd like to warn about issues in previously mentioned options.

    applicationVariants.all {
        val variantName = name
        sourceSets {
            getByName("main") {
                java.srcDir(File("build/generated/ksp/$variantName/kotlin"))
            }
        }
    }

sourceSets is not variant aware.
This code adds generated code from all build variants to the main source set.
E.g. generated code for "debug" and "release" build variants will be in "main" source set.
Print out source sets to see the final state.
It goes against the idea of build variants. This is probably not what you want.

configure<BaseExtension> {
    buildVariants.configureEach {
        sourceSets {
            named(name).configure {
                java.srcDir("build/generated/ksp/$name/kotlin")
            }
        }
    }
}

This alternative has another issue.
It adds generated code as input and breaks build cache.
I'll show this on example.

First clean build:

./gradlew :module:clean  :module:kspReleaseKotlin -Dorg.gradle.caching.debug=true

Appending input file fingerprints for 'source' to build cache key: xxx - RELATIVE_PATH{/project/module/src/main/java/.../Clazz.kt' / ...}

There were only sources as input for this task.
Now, lets run again:

./gradlew  :module:kspReleaseKotlin -Dorg.gradle.caching.debug=true

Appending input file fingerprints for 'source' to build cache key: yyy - RELATIVE_PATH{/project/module/build/generated/ksp/release/kotlin/<generated>, /project/module/src/main/java/.../Clazz.kt' / ...}

Here we see generated files as an addition to original sources.
It causes a cache miss. The output is not "stable".

For android folks who want to set kotlin sourceSets, we can configure it this way

android.applicationVariants.all { variant ->
    kotlin.sourceSets {
        def name = variant.name
        getByName(name) {
            kotlin.srcDir("build/generated/ksp/$name/kotlin")
        }
    }
}

For build.gradle.kts

    android.applicationVariants.all {
        kotlin {
            sourceSets {
                getByName(name) {
                    kotlin.srcDir("build/generated/ksp/$name/kotlin")
                }
            }
        }
    }

@eugene-krivobokov can you suggest correct solution for Android when using build variants? Thank you 🙏

Unfortunately, I haven't found it yet.

After upgrading to Android Studio Electric Eel the following solution didn't work anymore:

android {
    libraryVariants.all {
        kotlin.sourceSets {
            getByName(name) {
                kotlin.srcDir("build/generated/ksp/${name}/kotlin")
            }
        }
    }
}

But this one seems to work fine:

android {
    kotlin {
        sourceSets {
            debug {
                kotlin.srcDir("build/generated/ksp/debug/kotlin")
            }
            release {
                kotlin.srcDir("build/generated/ksp/release/kotlin")
            }
        }
    }
}

None of the above solutions work on Android Studio Flamingo | 2022.2.1 Canary 9
kotlin version: 1.7.20
ksp: 1.7.20-1.0.8
AGP: 8.0.0-alpha09
Gradle: 7.6

The solution that leinardi gave was working around canary 4 but I don't remember in which version it stopped.

    @Suppress("UnstableApiUsage")
    sourceSets.configureEach {
        kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin/")
    }

it works well on Android Studio.
it come from

commented

Fixed in e81d01f and will be available in 1.0.9. There should no longer workarounds be needed.

@ting-yuan using 1.0.11 it looks like the following is still required sorry posted on the wrong issue