sdeleuze
01/05/2023, 11:57 AMbuild.gradle.kts
syntax is possible. My biggest source of frustration https://github.com/gradle/gradle/issues/9268 seems to move forward, so that's good news. When using multiplatform projects, the other one I have hard time with is when there is this kind of code which is I think the idiomatic one documented:
sourceSets {
val commonMain by getting {
dependencies {
...
}
}
}
Because:
• commonMain
is marked as never used in the IDE, how is it technically taken in account?
• No discoverablity via autocomplete
• I understand the technical reasons for val commonMain by getting
but continues to looks to bit weird to me and not super approachable for beginners
• It seems possible to write a much nicer version but I think it works only for commonMain
not for platform specific variants:
sourceSets {
commonMain {
dependencies {
...
}
}
}
• Using val commonMain
when there is the commonMain
getter mentioned above is confusing
I can understand that Kotlin team don't want to pollute the DSL with all the crazy native platforms supported, but I am wondering if middle term it could be possible to just write:
sourceSets {
commonMain {
dependencies {
...
}
}
jvmMain {
dependencies {
...
}
}
}
Not sure how, maybe by generating the right extensions based on the target configured on the project via a 2 passes approaches (not sure if that's possible)? Any thoughts? cc @eskatosmbonnin
01/05/2023, 12:01 PMgetByName("commonMain"){
// stuff
}
eskatos
01/05/2023, 12:10 PMmbonnin
01/05/2023, 12:15 PMmbonnin
01/05/2023, 12:16 PMgetByName("foo")
and create("bar")
in Kotlin scripts and give up trying to make it look exactly like its Groovy couterparteygraber
01/05/2023, 12:24 PMsdeleuze
01/05/2023, 12:25 PMval commonMain by getting
is promoted because it looks like a bit more statically typed and leverage some Kotlin magic to get the name from the variable. getByName("foo")
or create("bar")
avoid the "never used issue" and looks a bit more familiar syntax, but does not seems the end game solution to me. Passing a string is not really statically typed API with autocomplete which is the promise of Gradle Jotlin DSL.sdeleuze
01/05/2023, 12:26 PMsdeleuze
01/05/2023, 12:26 PMcommonMain
one)mbonnin
01/05/2023, 12:26 PMThere is already some 2 passes analysis to read the plugins I think, couldn't targets be parsed as well and related extensions created?
plugins {}
works because it's a top level block and there are lots of constraints on itmbonnin
01/05/2023, 12:27 PMsdeleuze
01/05/2023, 12:27 PMsdeleuze
01/05/2023, 12:27 PMmbonnin
01/05/2023, 12:27 PMmbonnin
01/05/2023, 12:28 PMsdeleuze
01/05/2023, 12:28 PMmbonnin
01/05/2023, 12:28 PMafterEvaluate {
kotlin {
// bla
}
}
mbonnin
01/05/2023, 12:28 PMmbonnin
01/05/2023, 12:29 PMsdeleuze
01/05/2023, 12:29 PMmbonnin
01/05/2023, 12:32 PMkotlin {
jvmMain() // jvmMain is created here
}
mbonnin
01/05/2023, 12:33 PMmbonnin
01/05/2023, 12:34 PMkotlin {
if (someCondition) {
jvmMain()
}
}
sdeleuze
01/05/2023, 12:34 PMkotlin {
jvm()
}
?mbonnin
01/05/2023, 12:34 PMmbonnin
01/05/2023, 12:35 PMplugins {}
blockmbonnin
01/05/2023, 12:35 PMsdeleuze
01/05/2023, 12:36 PMsdeleuze
01/05/2023, 12:36 PMkotlin { }
I think that's ok.mbonnin
01/05/2023, 12:40 PMapproximative analysis via parsingFWIW (and AFAIK) this is not how it's done for plugins, it's actually calling
apply()
, running the code and reading the container values that have been contributedmbonnin
01/05/2023, 12:44 PMAdam S
01/05/2023, 12:44 PMsourceSets.commonMain {}
in kts scriptssdeleuze
01/05/2023, 12:45 PMOleg Yukhnevich
01/05/2023, 12:45 PMjvm
target in some plugin (f.e. convention plugin) and apply it in your project, you will have autocomplete for jvmMain
and jvmTest
- the same will work for any other sourceSet created in this plugin (even custom, like nativeMain
)
f.e.
jvm-convention.gradle.kts:
plugins {
kotlin("multiplatform")
}
kotlin {
jvm()
}
and in some module:
build.gradle.kts:
plugins {
id("jvm-convention")
}
kotlin {
sourceSets {
jvmMain { //will be generated type-safe accessor, even IDE will resolve it
}
}
}
Adam S
01/05/2023, 12:45 PMYes that’s mentioned in my original messagesorry I misunderstood!
sdeleuze
01/05/2023, 12:46 PMOleg Yukhnevich
01/05/2023, 12:46 PMcommonMain
as it’s created inside kotlin-multiplatform
pluginsdeleuze
01/05/2023, 12:46 PMAdam S
01/05/2023, 12:49 PMcommonMain
vs jvmMain
accessors. kotlin.sourceSets
is a NamedDomainObjectContainer
, and Gradle will generate Kotlin accessors for any named element so long as the elements are added before they are needed.Big Chungus
01/05/2023, 12:51 PMgetByName
and create
you should use named
and register
respectively to avoid eager initialisation.Adam S
01/05/2023, 12:52 PM// buildSrc/src/main/kotlin/some-convention.gradle.kts
val myConfiguration by configurations.registering { ...}
because then Gradle will generate an accessor
// build.gradle.kts
plugins {
`some-convention`
}
dependencies {
Big Chungus
01/05/2023, 12:52 PMsdeleuze
01/05/2023, 12:54 PMplugins {
kotlin("multilatform") version "1.8.0"
}
Like there is already:
ialization of:
plugins {
kotlin("jvm") version "1.8.0"
}
For Wasm whihc was my use case, there could be maybe:
ialization of:
plugins {
kotlin("wasm") version "1.8.0"
}
And that would create the related accesssors automaticalyy.Vampire
01/05/2023, 12:55 PMhttps://github.com/gradle/gradle/issues/9268 seems to move forwardYeah, they work on a compiler plugin that makes it possible, hopefully they can finish that any time. 🙂
•Theis marked as never used in the IDE, how is it technically taken in account?commonMain
by
is Kotlin property delegate mechanism. While calculating the actual delegate to use, the delegate mechanism can access the property name. So the name is acutally used. If IJ shows it as unused, that's imho a bug in IJ.
I personally prefer those delegates over the string variant Martin suggested for refactoring and reuse, if just IJ would not show them as unused.
No discoverablity via autocompleteThat's the same for all of these named domain object containers Accessors that can then be autocompleted like the
commonMain
if you use the sourceSets
within kotlin { ... }
are generated from applying the plugins in the plugins { ... }
block to a dummy project and investigating which things were added. commonMain
is always added, so an accessor can be generated. jvmMain
for example is only added if kotlin { jvm() }
is done, so on that dummy project is not present and so no accessor can be generated. That is the price for a type-safe DSL.
Targets are pretty standardized, could not be the end of te world to parse ...The point is, that this 2-phase thing is done by Gradle uniformly no matter which plugins are applied, not by the Kotlin plugin. So having special handling for Kotlin targets would introduce Kotlin plugin specifics into the Gradle core and that would not be too clean designwise unless some pluggable approach is invented. I think I made a feature request for that quite some time ago, but do not find it right now.
Big Chungus
01/05/2023, 12:56 PMVampire
01/05/2023, 12:56 PMmbonnin
01/05/2023, 12:56 PMsdeleuze
01/05/2023, 12:56 PMOleg Yukhnevich
01/05/2023, 12:57 PMsdeleuze
01/05/2023, 12:59 PMSo maybe we need a 3 passes analysis 😅for example is only added ifjvmMain
is done, so on that dummy project is not present and so no accessor can be generated. That is the price for a type-safe DSL.kotlin { jvm() }
Adam S
01/05/2023, 1:00 PMsourceSets {
val commonMain by getting {}
val commonTest by getting {}
val nativeMain by creating { dependsOn(commonMain) }
val nativeTest by creating { dependsOn(commonTest) }
// Linux
val linuxX64Main by getting { dependsOn(nativeMain) }
val linuxX64Test by getting { dependsOn(nativeTest) }
// Windows - MinGW
val mingwX64Main by getting { dependsOn(nativeMain) }
val mingwX64Test by getting { dependsOn(nativeTest) }
// and so on...
full code here: build-logic/src/main/kotlin/ks3/conventions/lang/kotlin-multiplatform-native.gradle.kts
sdeleuze
01/05/2023, 1:02 PMOleg Yukhnevich
01/05/2023, 1:06 PMVampire
01/05/2023, 1:12 PMSo maybe we need a 3 passes analysisYou cannot make an automated 3 pass analysis. Gradle cannot know what exactly to copy over to the dummy project.
sdeleuze
01/05/2023, 1:13 PMVampire
01/05/2023, 1:46 PM