ribesg
03/21/2024, 1:59 PMkotlin {
jvm()
}
Then I put a file in commonMain and can use it fine from jvmMain. Why?
I even confirmed there is no dependency set:
afterEvaluate {
kotlin.sourceSets
.filterNot { it.name.endsWith("Test") }
.forEach { println("${it.name} [${it.dependsOn.joinToString { it.name }}]") }
}
> Configure project :
commonMain []
jvmMain []
How does it work? I was expecting to need to call applyDefaultHierarchyTemplate()
, which does produce the expected result.
> Configure project :
commonMain []
jvmMain [commonMain]
The documentation states that this dependency exists, but why is it not in dependsOn
? Where is it defined?Michael Krussel
03/21/2024, 2:25 PMjvm
, ios
, android
, etc, automatically adds the dependency on commonMain
even without the default hierarchy template.ribesg
03/21/2024, 2:26 PM> Configure project :
commonMain []
commonTest []
jvmMain []
jvmTest []
linuxArm64Main []
linuxArm64Test []
linuxX64Main []
linuxX64Test []
macosArm64Main []
macosArm64Test []
macosX64Main []
macosX64Test []
mingwX64Main []
mingwX64Test []
zsmb
03/21/2024, 2:49 PMapplyDefaultHierarchyTemplate
if you'll add additional source sets to the project.ribesg
03/21/2024, 2:52 PMapplyDefaultHierarchyTemplate
I don't see intermediate source sets in kotlin.sourceSets
Anton Lakotka [JB]
03/21/2024, 4:38 PMafterEvaluate
block.
Please let me know your use case, I'll try to help you.ribesg
03/21/2024, 4:45 PMafterEvaluate
block. Good opportunity to explain how to create a simple custom task. I doubt that this uncertainty will cause problem to anyone doing something serious, as they would probably use a task anyway, it's just a little unexpected.Anton Lakotka [JB]
03/21/2024, 4:46 PMI decided to use a task instead of just a flyingyes for your use case it is the best way to do. During task execution there is a guarantee that Configuration State is final.block. Good opportunity to explain how to create a simple custom task.afterEvaluate
Anton Lakotka [JB]
03/21/2024, 4:48 PMit's just a little unexpected.thank you for the input anyway! I'll think on how we can improve the message that state is not final OR finding a way of finalizing state as early as possible.
ribesg
03/22/2024, 1:35 PMkotlin {
jvm()
linuxArm64()
linuxX64()
macosArm64()
macosX64()
mingwX64()
targets.withType<KotlinNativeTarget> {
binaries.executable()
}
}
dependencies {
"commonMainImplementation"(libs.bundles.common.main)
"appleMainImplementation"(libs.bundles.apple.main)
"jvmMainImplementation"(libs.bundles.jvm.main)
"linuxMainImplementation"(libs.bundles.linux.main)
"mingwMainImplementation"(libs.bundles.mingw.main)
}
With this configuration, the intermediate source sets do not seem to be defined before the dependencies
block. It fails to find "appleMainImplementation"
for example :
org.gradle.api.artifacts.UnknownConfigurationException: Configuration with name 'appleMainImplementation' not found.
at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.createNotFoundException(DefaultConfigurationContainer.java:124)
at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:334)
at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.getByName(DefaultConfigurationContainer.java:114)
at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.getByName(DefaultConfigurationContainer.java:54)
at org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.addProvider(DefaultDependencyHandler.java:128)
at org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.addProvider(DefaultDependencyHandler.java:133)
at org.gradle.kotlin.dsl.support.delegates.DependencyHandlerDelegate.addProvider(DependencyHandlerDelegate.kt:62)
at org.gradle.kotlin.dsl.DependencyHandlerScope.invoke(DependencyHandlerScope.kt:596)
Calling applyDefaultHierarchyTemplate()
works around this, but again it's not obvious when the source sets are availableAnton Lakotka [JB]
03/22/2024, 1:38 PMkotlin {
sourceSets {
commonMain {
dependencies {
api(...)
implementation(...)
}
}
}
}
also good to know that parent source set dependencies are propagated to the underlying children source sets.
in your case it seems like it is enough to define only commonMain dependencies.ribesg
03/22/2024, 1:40 PMapplyDefaultHierarchyTemplate()
and use the dependencies
block unless there are other differencesAnton Lakotka [JB]
03/22/2024, 1:41 PMribesg
03/22/2024, 1:44 PMsourceSets {
commonMain.dependencies {
implementation(libs.bundles.common.main)
}
appleMain.dependencies {
implementation(libs.bundles.apple.main)
}
jvmMain.dependencies {
implementation(libs.bundles.jvm.main)
}
linuxMain.dependencies {
implementation(libs.bundles.linux.main)
}
mingwMain.dependencies {
implementation(libs.bundles.mingw.main)
}
}
Anton Lakotka [JB]
03/22/2024, 1:45 PMval dependencyBundles = mapOf("commonMain" to libs.bundles.commonMain, ...)
kotlin.sourceSets.configureEach {
val bundle = dependencyBundles[name] ?: return@configureEach
dependencies { implementation(bundle) }
}
Anton Lakotka [JB]
03/22/2024, 1:46 PMribesg
03/22/2024, 1:52 PMcommonMain-implementation
in the standard libs.versions.toml
and it would just work.
I like your solution but it goes back to relying on Strings and I don't think it's appropriate in my case as I'm making educational material.
It's not to my taste but I should use my last snippet I think