CLOVIS
02/27/2024, 4:47 PMjsMain
source set doesn't depend on the commonMain
source set?
I first learned of this here, but we couldn't find any documentation explaining why that is.tapchicoma
02/28/2024, 10:10 AMAnton Lakotka [JB]
03/06/2024, 6:43 PMafterEvaluate
block.
We can only guarantee that the state is final once all tasks are configured and ready for execution.
So this will not work:
afterEvaluate {
println(kotlin.sourceSets.getByName("jsMain").dependsOn)
}
but this should work:
gradle.taskGraph.whenReady {
println(kotlin.sourceSets.getByName("jsMain").dependsOn) // prints [source set commonMain]
}
However, you should never modify anything in the gradle.taskGraph.whenReady
block. The state is final and is meant for reading purposes only.
If you want to get all source sets of certain target (compilation) and do something with it (like collect all related resources and etc). You should use KotlinCompilation.allSourceSets
API.
Let me show you an example of how you can do that:
kotlin {
jvm()
js()
// user can configure source sets as they want
}
val archiveKotlinJsResources by tasks.registering(Zip::class) {
val jsMainCompilation = kotlin.js().compilations.getByName("main")
val allJsResources = project.files().from({
jsMainCompilation.allKotlinSourceSets.map { it.resources.sourceDirectories }
})
from(allJsResources)
archiveClassifier.set("kjs-assets")
}
With this setup, there is a guarantee that all intermediate source sets that are included to JS target will be present in allKotlinSourceSets
when Gradle will configure Task Graph.Anton Lakotka [JB]
03/06/2024, 6:44 PMmbonnin
03/06/2024, 6:47 PMandroidInstrumentedTest
does not depend on commonTest
. Would be nice to have this diagram but with full source sets details (mermaid maybe?)CLOVIS
03/06/2024, 6:48 PMmbonnin
03/06/2024, 6:50 PMAnton Lakotka [JB]
03/06/2024, 6:55 PMSomewhat related, I just realized today thatYes, this is intentional. As some users want and others do not. That is why we made a possible to configure it on user side. here is how:does not depend onandroidInstrumentedTest
commonTest
kotlin {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
androidTarget {
instrumentedTestVariant {
sourceSetTree.set(KotlinSourceSetTree.test) // make it depend on commonTest
sourceSetTree.set(KotlinSourceSetTree.instrumentedTest) // make it to not depend on commonTest
}
unitTestVariant {
sourceSetTree.set(KotlinSourceSetTree.test) // make it depend on commonTest
sourceSetTree.set(KotlinSourceSetTree.unitTest) // make it to not depend on commonTest
}
}
}
This is an experimental API and gives the user a lot of flexibility. As you can change sourceSetTree
to anything you want. But the configuration options I mentioned above are the most common ones.mbonnin
03/06/2024, 6:56 PMmbonnin
03/06/2024, 6:56 PMmbonnin
03/06/2024, 6:57 PMAnton Lakotka [JB]
03/06/2024, 7:05 PMmbonnin
03/06/2024, 7:07 PMCLOVIS
03/07/2024, 7:46 AMmbonnin
03/07/2024, 7:55 AMCLOVIS
03/07/2024, 8:46 AMmbonnin
03/07/2024, 9:16 AMCLOVIS
03/07/2024, 1:00 PMCLOVIS
03/09/2024, 7:31 PMkotlin.js()
come from? I would have assumed from the kotlin
extension, but it doesn't seem to be available on the KotlinProjectExtension
type.Edoardo Luppi
03/09/2024, 7:32 PMKotlinMultiplatformExtension
CLOVIS
03/09/2024, 7:33 PMCLOVIS
03/09/2024, 7:37 PMAnton Lakotka [JB]
03/09/2024, 8:12 PMkotlin
with type KotlinMultiplatformExtension
this is stable and public API.
So you can safely request it in your Gradle Plugin like this:
project.extensions.getByType<KotlinMultiplatformExtension>()
If your plugin can work with both Multiplatform and Kotlin/JVM plugins then you can get it by name and do when is
checks.
val kotlinExtension = project.extensions.getByName>("kotlin")
when (kotlinExtension) {
is KotlinMultiplatform -> TODO("KMP")
is KotlinJvmProjectExtension -> TODO("JVM")
else -> TODO("Unknown Plugin")
}
It is important to say that if you want to get an extension of some Gradle Plugin you should ensure that this plugin is applied.
the safest way is to write this hook:
project.plugins.withId("org.jetbrains.kotlin.multiplatform") {
project.extensions.getByType<...>()
}
Anton Lakotka [JB]
03/09/2024, 8:14 PMEdoardo Luppi
03/10/2024, 1:34 PMIt's internal
I apply the first rule of Java programmers: a private declaration is a public declaration, it just doesn't know it, yet.
CLOVIS
03/13/2024, 3:29 PM