I’m trying to create a native CLI utility that use...
# kotlin-native
s
I’m trying to create a native CLI utility that uses different Ktor engine per platform, and I’m starting with Mac. The project has a common “nativeMain” module for all platforms. So I have modified my build like this:
Copy code
kotlin {
...
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosX64("native")
        hostOs == "Linux" -> linuxX64("native")
...
    }

...
    sourceSets {
        val nativeMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.5")
            }
        }

        val nativeMac by creating {
            dependsOn(nativeMain)
            dependencies {
                implementation("io.ktor:ktor-client-darwin:$ktorVersion")
            }
        }
    }
}
And I’m getting
Copy code
The Kotlin source set nativeMac was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See <https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets>
But I can’t figure how to “add a source set to a target’s compilation”, also the link in the warning goes to nowhere.
v
Do you have any binaries defined?
e
you need to add
nativeMac
to something. also just go ahead and add all targets regardless of the host, the ones which can't be built will be automatically skipped
Copy code
kotlin {
    macosX64()
    linuxX64()

    sourceSets {
        val nativeMac by creating { ... }
        val macosX64Main by getting {
            dependsOn(nativeMac)
also the new https://kotlinlang.org/docs/multiplatform-hierarchy.html#default-hierarchy will give you
macosX64Main
macosMain
appleMain
nativeMain
commonMain
s
The binaries is a vanilla
Copy code
nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
I seem to have solved this with
Copy code
val nativeMain by getting {
            when (nativeTarget.konanTarget) {
                KonanTarget.LINUX_ARM64 -> dependsOn(nativeLinux)
                KonanTarget.LINUX_X64 -> dependsOn(nativeLinux)
                KonanTarget.MACOS_ARM64 -> dependsOn(nativeMac)
                KonanTarget.MACOS_X64 -> dependsOn(nativeMac)
                KonanTarget.MINGW_X64 -> dependsOn(nativeWindows)
                else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
            }
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.5")
            }
        }
My mistake was that I was trying to organize the hierarchy from the root to leaves, making nativeMac depend on nativeMain, and it needs to be opposite. Having the warning link broken did not help, too. Btw, thanks for the hierarchy link above, I just did not see it before, IMO it should be at the root of multiplatform chapter.
e
I really wouldn't bother with calling the target
native
. that'll collide with the new automatic hierarchy and is unnecessary when you can just register all targets without issue
s
@ephemient Sorry, didn’t really get what you meant. The “native” target is created by IntelliJ as part of the Multiplatform Native Application template.
e
I don't use any of the templates so I don't know why they do it like that… I mean
Copy code
kotlin {
    linuxArm64()
    linuxX64()
    macosArm64()
    macosX64()
    mingwX64()
or whatever the full set of your desired targets is
s
You know, I tend to trust those guys at JetBrains… 😉
e
well that matches the online docs