c

    capitalthree

    3 years ago
    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

    3 years ago
    Here you go! This is a project that provides for 2 android apps and a single ios app: Top build.gradle:
    // 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

    3 years ago
    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

    3 years ago
    you want a jvm project top level that has a multiplatform contained inside?
    c

    capitalthree

    3 years ago
    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

    3 years ago
    Let me look at what that project spins up so I can help
    c

    capitalthree

    3 years ago
    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

    3 years ago
    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.
    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

    3 years ago
    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

    3 years ago
    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

    3 years ago
    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?
    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

    3 years ago
    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

    3 years ago
    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

    3 years ago
    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:
    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

    3 years ago
    ok how do I know whether to prepend a colon or not?
    b

    Benjamin Charais

    3 years ago
    since you’re only doing one layer, you should not need to worry about any more than a single colon
    c

    capitalthree

    3 years ago
    so SharedCode is the top level project and colons are for the subprojects?
    b

    Benjamin Charais

    3 years ago
    that was just a typo my bad 😂
    In my case… the
    SharedCode
    is being treated as a library.
    c

    capitalthree

    3 years ago
    so should mine look like
    include("websystem", ":dbsystem")
    ?
    if I'm naming the subproject dbsystem
    b

    Benjamin Charais

    3 years ago
    I would say yes, use a colon
    c

    capitalthree

    3 years ago
    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

    3 years ago
    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

    3 years ago
    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

    3 years ago
    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

    3 years ago
    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

    3 years ago
    nope just like it’s standalone
    c

    capitalthree

    3 years ago
    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

    3 years ago
    Been taking a break for a while, but I'm glad you got it going!