Can someone please explain me why i can use `runBlocking` in `linuxMain` and in `macosMain` but i ca...
b
Can someone please explain me why i can use
runBlocking
in
linuxMain
and in
macosMain
but i cannot use it wether in my own source set
nativeMain
nor in
commonMain
. Do i need add some sort of configuration to the source set?
Copy code
plugins {
    kotlin("multiplatform")
}

kotlin {
    linuxX64("linux") {
        binaries {
            executable()
        }
    }

    macosX64("macos") {
        binaries {
            executable()
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(kotlin("stdlib-common"))

                implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1-native-mt")
            }
        }

        val nativeMain by creating {
            dependsOn(commonMain)
        }

        val macosMain by getting {
            dependsOn(nativeMain)
        }

        val linuxMain by getting {
            dependsOn(nativeMain)
        }

    }
}
s
runBlocking is not defined in ‘common’ because it doesn’t have implementations in all targets that Kotlin supports, namely Javascript. You can use
expect/actual
to define it in your common source set. The actual part on each platform can just be an alias.
m
Shouldn’t commonizer make it available to
nativeMain
? 🤔
b
Ok, i've managed to use 
runBlocking
 in 
commonMain
 with following: commonMain
Copy code
expect fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T
linuxMain, macosMain
Copy code
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking as runBlockingNative
import kotlin.coroutines.CoroutineContext

actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T = runBlockingNative(context, block)
But why cannot i just define/use it in
nativeMain
?
r
You can use it, but the IDE doesn't resolve it. It'll still build from gradle. In theory hmpp/commonizer should help here but I've never gotten it to work for runBlocking.
m
Whats the reason for ide not resolving these classes when they still build fine? I have this problem ina few places in my project and can't fix it. Not a big deal but annoyance
a
Enable granular metadata if you don't target js
m
You mean
kotlin.mpp.enableGranularSourceSetsMetadata=true
? I have it enabled, but the problem persists
a
Should work, if you don't have js target
m
I don't have js. Right now it seems to work fine in the
shared
module (the one compiled for swift) but is messed up in another module. • module1 (multiplatform) • module2 (jvm, depends on module1) • shared (multiplatform, depends on module1 and kapt-module2) • settings.gradle for the whole project has the enableGranularEtc=true And in module2 Android Studio says
Unresolved reference
for classes from module1. Everything is fine in shared
a
The commonizer cannot deal with this case as it’s capable of sharing only Kotlin/Native platform libraries at the moment(see README.md). The reason why
runBlocking
is not available from common code is that it is not supported for the js target, as already mentioned. Expect/Actual mechanism use seems to be the best option. Related issues: https://github.com/Kotlin/kotlinx.coroutines/issues/195, https://github.com/Kotlin/kotlinx.coroutines/issues/1039, https://youtrack.jetbrains.com/issue/KT-29403
m
@Artyom Degtyarev [JB]
nativeMain
mentioned before only consists of native targets. https://kotlinlang.slack.com/archives/C3PQML5NU/p1610477636230700
a
Hmm. If the library was published as described in the documentation, this should work correctly, with the hierarchical project structure enabled. Thank you for noticing, @Marc Knaup 🙂 To be honest, I haven’t checked it locally. If the problem seems reproducible, it would be nice to report it on the youtrack with a project to play with.
b
Sorry, i haven't had the granular Metadata enabled. Adding
kotlin.mpp.enableGranularSourceSetsMetadata=true
to the
gradle.properties
seems to help.
a
Yeah! That's what I've said, it runs commonizer to have all the common things available in commonMain, and so on (if you have a common module in between the source tree)
If you add
js
as target, you'd not get it on
commonMain
, but on
nativeMain
:)