https://kotlinlang.org logo
c

capitalthree

06/24/2019, 9:27 PM
can anyone point me to any example of a gradle kotlin multiplatform project that has a subproject? Even if nobody can give me a specific answer about scala, I am pretty sure I can make it work as a subproject but I don't know how to make the jvm compile task include the subproject properly
b

Benjamin Charais

06/24/2019, 9:29 PM
Here you go! This is a project that provides for 2 android apps and a single ios app: Top build.gradle:
Copy code
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.31'
    ext.coroutines_version = '1.2.1'
    ext.klockVersion = "1.4.0"
    
    // Reduced these values to get serialization to work
    ext.serialization_version = "0.10.0"
    ext.ktor_version = '1.1.4'

    ext.dokka_version = '0.9.17'
    
    
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url "<https://kotlin.bintray.com/kotlinx>" }
        maven { url "<https://kotlin.bintray.com/ktor>" }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"

        classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:$dokka_version"

        classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta04'

        classpath "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
    }
}


allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url "<https://kotlin.bintray.com/kotlinx>" }
        maven { url "<https://kotlin.bintray.com/ktor>" }
    }
}
SharedCode module build.gradle: https://pastebin.com/K5yawwtv
Hope this helps. This is a build system I wrote so if you have questions let me know.
c

capitalthree

06/24/2019, 9:33 PM
So in this example, the jvm specific project is the top level project and then the kotlin multiplatform project is a submodule? that's the inverse of what I am trying, but if you say it's easier, I will try to emulate it.
b

Benjamin Charais

06/24/2019, 9:35 PM
you want a jvm project top level that has a multiplatform contained inside?
c

capitalthree

06/24/2019, 9:41 PM
No, I thought that was what you were offering. I might be misunderstanding. I actually don't care what project is contained inside, but the important part is that the scala project will be called by the kotlin code in jvmMain
I should clarify, the kotlin multiplatform project I'm starting with is intellij project template for a webapp with js and jvm. I just want to also add scala code for database access.
b

Benjamin Charais

06/24/2019, 9:57 PM
Let me look at what that project spins up so I can help
c

capitalthree

06/24/2019, 9:58 PM
I can share what I currently have, but it's just the exact same thing rewritten as gradle.kts
thank you very much for your help!
here, I stuck it on github, just in case that's convenient, https://github.com/alexbobp/mowfev It was going to end up there eventually.
b

Benjamin Charais

06/24/2019, 10:06 PM
I see where your confusion comes from with my code, since it’s done in multiple build.gradle… The first one I sent would be equivalent to the one provided in the intellij sample. Kotlin can not reference pre-compilation Scala, but can access compiled Scala. It sounds like the scala needs to go into the jvmMain portion and needs to have the gradle configuration to compile Scala (This is not something I am familiar with sorry, cant help here) Then once that compiles internally, the front end portion should be able to digest the Scala code.
Copy code
Kotlin's Java interop works due to the fact that Kotlin incorporates a parser for Java source code, which allows to reference declarations which haven't been compiled yet. Kotlin doesn't incorporate a Scala parser, so it can only invoke Scala code which has been compiled; the reverse is also true. Thus I don't think that full three-way interop could be possible without a lot of extra work.
c

capitalthree

06/24/2019, 10:07 PM
I was actually just about to provide a working standalone gradle script to build a scala project, would that help?
it's ok to not have full interop both ways, I just want to expose a library in scala that can be consumed by kotlin
b

Benjamin Charais

06/24/2019, 10:09 PM
Easy answer is yes, that is possible, but Kotlin can only work with compiled Scala, and Scala can technically call compiled Kotlin
So if you modify your build to first compile the Scala before Kotlin begins trying to work with it, then you shouldn’t have any issues
c

capitalthree

06/24/2019, 10:09 PM
so I can do it all without a subproject?
I'm sorry I am so dense, I find gradle pretty baffling still... are you suggesting I have it build the scala subproject first, or that I don't need a subproject at all?
Copy code
plugins {
    id 'scala'
}

dependencies {
    compile 'org.scala-lang:scala-library:2.11.12'
}

repositories {
    jcenter()
}
this is a very simple working scala library project
I know how to set the tasks to run in order but not how to make sure that the kotlin will build against the compile output from the compileScala task
actually I can probably figure that out... thank you for your help
b

Benjamin Charais

06/24/2019, 10:14 PM
No problem! My personal opinion, I think a subproject would make it easier, because it creates a separation of ideas
Gradle is a bit of a headtrip for sure.
c

capitalthree

06/24/2019, 10:16 PM
ok then, I am happy to do it that way.
I just have 0 experience with subprojects, and how to reference their compiled output, and whatnot
b

Benjamin Charais

06/24/2019, 10:17 PM
I can give you the key points, as it would be a bit tricky to fully explain. Subprojects in gradle are as simple as: settings.gradle:
Copy code
include ':android', 'SharedCode', ':iosApp'
This would create 3 modules in intellij. Then in order to create a subproject, it just requires another
build.gradle
inside the module itself. Boom subproject!! referencing output can be done with sourceSets and outputDir
c

capitalthree

06/24/2019, 10:19 PM
ok how do I know whether to prepend a colon or not?
b

Benjamin Charais

06/24/2019, 10:19 PM
since you’re only doing one layer, you should not need to worry about any more than a single colon
c

capitalthree

06/24/2019, 10:20 PM
so SharedCode is the top level project and colons are for the subprojects?
b

Benjamin Charais

06/24/2019, 10:20 PM
that was just a typo my bad 😂
In my case… the
SharedCode
is being treated as a library.
c

capitalthree

06/24/2019, 10:21 PM
so should mine look like
include("websystem", ":dbsystem")
?
if I'm naming the subproject dbsystem
b

Benjamin Charais

06/24/2019, 10:21 PM
I would say yes, use a colon
c

capitalthree

06/24/2019, 10:22 PM
and then in the jvmMain dependencies block I put
implementation(project("dbsystem"))
, is that right? do I want a colon there too?
is it totally unnecessary? I see nothing like it in your examples
b

Benjamin Charais

06/24/2019, 10:26 PM
nope dont need to reference it in the subproject
you only would need to reference it in another project that depends on it.
c

capitalthree

06/24/2019, 10:27 PM
I am talking about referencing the scala subproject from the kotlin multiplatform parent project
or should I invert it and put the kotlin multiplatform project on the inside?
b

Benjamin Charais

06/24/2019, 10:29 PM
I would have scala be the child. So I’m unfamiliar with the kts gradle stuff (haven’t had time to convert my work over) But that looks right. I would reference it as an
api
not
implementation
and it would still receive a colon
c

capitalthree

06/24/2019, 10:30 PM
ok! thanks!
and one other question, should the build.gradle for the scala project look identical to how it would if it were a standalone gradle project? or what are the differences for a child project?
b

Benjamin Charais

06/24/2019, 10:30 PM
nope just like it’s standalone
c

capitalthree

06/24/2019, 10:33 PM
Unable to find a matching configuration of project :dbsystem: None of the consumable configurations have attributes.
what does this mean?
do I need something in dbsystem/settings.gradle.kts?
besides
rootProject.name = "dbsystem"
I committed what I've got, in case it's easier to try and debug the broken project in totality. Not that I expect you to do so, I've wasted enough of your time. Thanks for the help, I'll do more gradle reading
oh no, I have made surely the dumbest mistake... I had a build.gradle.kts.gradle, so it was being ignored. fixing that!
@Benjamin Charais ok, it works, I confirmed I'm calling scala from kotlin! thank you very much 😄
b

Benjamin Charais

06/25/2019, 12:32 AM
Been taking a break for a while, but I'm glad you got it going!