Hi everyone, I have an android project set up with...
# ksp
d
Hi everyone, I have an android project set up with ksp. When I am building the debug and release version in succession, I am getting a compile-time error saying that duplicate declarations are present. The issue is that ksp is building the same code under the debug folder and in the release folder. How can I solve this? I am attaching a screenshot for reference.
Copy code
kotlin.sourceSets.main {
    kotlin.srcDirs(
        file("$buildDir/generated/ksp/"),
    )
}

ksp {
    arg("ignoreGenericArgs", "false")
}
these lines are added to my app-module gradle file
t
file("$buildDir/generated/ksp/")
includes generated sources from both release and debug. Can you try to remove it?
d
No that does not work, then my activity cannot find/import the generated code.
More specifically, the following code is generating separate package names for debug and release
Copy code
val symbols = resolver
    .getSymbolsWithAnnotation("my_annotation")
    .filterIsInstance<KSClassDeclaration>()

symbols.forEach {
    val packageName = it.packageName.asString()
    val file = codeGenerator.createNewFile(
        dependencies = Dependencies(false, *resolver.getAllFiles().toList().toTypedArray()),
        packageName = packageName,
        fileName = it.simpleName.asString()
    )
}
it.packageName.asString()
is evaluated to
<http://debug.kotlin.my|debug.kotlin.my>_package_name
and
<http://release.kotlin.my|release.kotlin.my>_package_name
Can we somehow manipulate that?
o
What if you'd drop the `debug`/`release` prefix by changing the
packageName
assignment like this?
Copy code
val packageName = it.packageName.asString().substringAfter('.')
d
No luck, even if I provide any custom
packageName
in
codeGenerator
, it is still prefixed with
debug.kotlin
o
OK, while I'm not familiar with the Android build system, in this case it looks like
ksp
is treating
debug
and
release
like different source sets. In this case, maybe the example project mentioned in issue https://github.com/google/ksp/issues/965 could help you in restricting code generation to just
debug
or
release
, but not both.
d
Thanks. This looks helpful, will try this once.
👍 1
Hi, I tried this solution but didn't work for me. I was able to get source set from
Copy code
codeGenerator.generatedFile.first().toString().sourceSetBelow("ksp")
but getting it for my file containing the annotation is giving me the path of the file. Not sure how can we determine the source set from that.
Copy code
/Users/dilrajsingh/Desktop/Code/safe-compose-args/app/src/main/java/com/compose/type_safe_args/safecomposeargs/NavigationGraph.kt
This is what I get for
inputSourceSet
Though I found a solution
Replacing
Copy code
kotlin.sourceSets.main {
    kotlin.srcDirs(
        file("$buildDir/generated/ksp/"),
    )
}
with
Copy code
androidComponents.onVariants {variant ->
    kotlin.sourceSets.findByName(variant.name)?.kotlin?.srcDirs(
        file("$buildDir/generated/ksp/${variant.name}/kotlin")
    )
}
works
👍 2
By this the IDE only includes generated files for the current source set
Thanks to everyone for the inputs, appreciate it.
j
The issue is mainly caused by android build variant, this variant specific logic looks reasonable. maybe we should do some work on KSP gradle plugin side to make it variant aware..
🙌 1
o
Since build variants effectively shape the source set hierarchy, it would be ideal for KSP to be more source set aware generically (for Android and Kotlin Multiplatform builds). That would include • making the KSP Gradle plugin automatically attach its generated directories to the respective source sets, and • passing input and output source sets to the
SymbolProcessor
for cases where generated code would differ by source set.
j
re Oliver: For the first item, this should already be done by KSP, it is just not available to IDE for indexing purpose therefore all the workaround (and also the issues comes with all these workarounds). For a normal Java AP this is also true, ultimate solution might be writing an IDE plugin, which is a separate effort, and doesn’t seems possible with only gradle plugin changes. For the second item, actually, after some thought, it might be easier for processors to accept some arguments, and you can pass the arguments to processor in
build.gradle
easily (via
ksp {}
extension, see KSP example project), and this way we can avoid having to introduce android variant specific logic (there could be other scenarios where you need to specify different source sets for different build task)
o
@Jiaxiang Thanks for looking into this. I possibly did not explain myself well enough, my intention was to refer to issue #965 and the example Multiplatform project I had provided (link in issue #965). So it would be ideal if we would not need to insert multiple redundant constructs such as •
kotlin.srcDir("build/generated/ksp/...")
, plus •
add("ksp...", ...)
, plus • wiring the KSP task dependencies between source sets
dependsOn(kspKotlinMetadata)
as seen in my example project's Gradle build script. I understood the documentation (KSP with Kotlin Multiplatform | Kotlin) to discourage using
ksp()
in Kotlin Multiplatform projects. If I got this wrong, using
ksp()
per source set would at least allow me to specify the output source set (although requiring additional build script boilerplate). What I'd still be missing is the input source set, as KSP (at least in my example) always processes files from multiple input source sets per invocation.
447 Views