Search code examples
androidgradlebuild.gradlekotlin-multiplatform

Why do we have androidMain in shared module in addition to the Android project's build.gradle.kts?


In KMM we have a build.gradle.kts for the shared module which includes amongst others:

sourceSets {
    val commonMain by getting {
        dependencies {
            //put your multiplatform dependencies here
            // ...
        }
    }
    val androidMain by getting { // note androidMain here
        dependencies {
            // some stuff like sqldelight android driver goes here
        }
    }

    // ...
}

In addition we also have a build.gradle.kts in the androidApp folder.

So, when would one put dependencies in the androidMain section of the shared module build.gradle.kts and when would one put it in the build.gradle.kts in the androidApp folder? Why do we have an androidMain section at all in the build.gradle.kts of the shared module if the shared module is supposed to be platform independent?


Solution

  • Why do we have an androidMain section at all in the build.gradle.kts of the shared module if the shared module is supposed to be platform independent?

    The shared module is not platform-independent. The source sets can be, for example commonMain. However, you can have androidMain, iosMain, etc. Those source sets are platform-specific.

    If you are using expect/actual, the compiler will look to satisfy all expect declarations. So, say you have:

    expect fun hello():String
    

    If you define Android and iOS as targets, you'll need an actual for each, in the shared Kotlin module.

    In androidMain:

    actual fun hello() = "Hi from Android"
    

    In iosMain:

    actual fun hello() = "Hi from iOS"
    

    If the compiler can't find a matching actual for each target to satisfy the expect, the build will fail. You can't put those actual declarations in the androidApp. They need to be satisfied directly in the shared module.