Federico d'Alonzo
11/18/2023, 6:59 PMTarget is a pretty "heavy" concept in terms of build setup.
As such, I have been experimenting a bit with the new multiplatform api, for example:
applyDefaultHierarchyTemplate {
common {
group("jvmCommon") {
withJvm()
}
}
}
correctly creates the hierarchy shown in image 1
, where I can create an expect in jvmCommonMain
and an actual in jvmMain
like in images 2
and 3
But there appears to be no way I know of to compile to the jvm target with multiple "settings", like kotlinOptions.jvmTarget
version.
This would've been done previously by creating multiple jvm targets as stated in the compatibility guide:
jvm("jvmKtor") { attributes.attribute(/* ... */) }
jvm("jvmOkHttp") { attributes.attribute(/* ... */) }
But this warning appears:
w: Kotlin Target 'jvm()' is already declared.
Declaring multiple Kotlin Targets of the same type is not recommended
and will become an error in the upcoming Kotlin releases.
Creating a compilation val secondary by compilations.creating
only seems to create an isolated jvmSecondary
source set which shares nothing with the main tree.
If I do create a kotlin source set tree by withSourceSetTree(KotlinSourceSetTree("secondary"))
inside the hierarchy template, then the rest of the source sets will appear (commonSecondary, jvmCommonSecondary...), but no expect/actual association exists, not even by associateWith(compilations.getByName("main"))
(which I understand is a way to let the current compilation see internal declarations from the associated compilation) in the secondary
compilation (plus, secondary
now appears as a test compilation).
I could directly depend on jvmCommonMain inside of the defaultSourceSet for the secondary compilation dependsOn(sourceSets.getByName("jvmCommonMain"))
, which actually appears to grant the behaviour I'm trying to achieve, but seems to be unwanted behaviour:
w: Following Kotlin Source Set groups can't depend on 'jvmCommonMain' together as they belong to different Kotlin Source Set Trees.
Source Sets from 'main' Tree:
* 'jvmMain'
Source Sets from 'secondary' Tree:
* 'jvmSecondary'
Please keep dependsOn edges only from one group and remove the others.
This warning appears even if I remove withSourceSetTree(KotlinSourceSetTree("secondary"))
or if I rename the compilation to secondaryMain
.
This brings me to my question:
Is there a way to emulate multiple jvm targets with expect/actual support with the new api?
I understand the approach described in the compatibility guide, but this seems to be a bit of a step-back as expect/actual is quite handy and easy to use compared to a manual check-and-switch for implementations.tapchicoma
11/20/2023, 12:26 PMFederico d'Alonzo
11/20/2023, 3:39 PMWhile the engine supports feature variants independently of the ecosystem, this feature is currently only available using the Java plugins.
A generalization of both concepts could be possible:
The concept of a source set tree and hierarchy system seems like a very good idea, but it could be expanded/refined by providing per-target flavors or variants.
As I understand it now, the system works by providing a common source-set tree structure (defaultHierarchy for example), which is pruned to only contain branches that point to an existing target, and further pruned for each compilation to only contain targets for which a compilation by that name exists. (in my secondary
compilation example, if I where to add a native target, that wouldn't appear in the secondary tree unless I add a secondary compilation under that target too).
As of now, the defaultSourceSet
for a target-specific compilation is the leaf source set for the whole structure.
A natural extension of this system would be providing target-specific-variants, possibly like so:
kotlin
jvm {
// NamedDomainObjectContainer<KotlinJvmCompilation(Build)Variant>
variants {
// \/ doesn't depend on name, also possible via "val <name> by getting", always exists
default {
// can do most of the things you would imagine, might shift the load from compilations, possibly?
}
val debug by creating {
kotlinOptions {
jvmTarget = "1.8"
}
}
val another by creating {
kotlinOptions {
jvmTarget = "17"
}
}
}
}
default source set locations could be provided like so:
https://i.gyazo.com/274f6b18356a055f85ca5efc82dd89c3.png▾
tapchicoma
11/20/2023, 3:42 PM