Search code examples
androidioskotlinkotlin-multiplatform

I'm getting this error in KMM: Cannot add a KotlinSourceSet with name 'iosMain' as a KotlinSourceSet with that name already exists


I'm getting the error in KMM, trying to add the ktor library. It says to add in iOS main, but if I add that it shows this error:

Cannot add a KotlinSourceSet with name 'iosMain' as a KotlinSourceSet with that name already exists.

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    id("org.jetbrains.compose")
}

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
    targetHierarchy.default()

    android {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
            isStatic = true
        }

        dependencies {
            implementation("io.ktor:ktor-client-darwin:2.3.5")
        }
    }

    sourceSets {
        val ktorVersion = "2.3.5"
        val commonMain by getting {
            dependencies {
                implementation(compose.runtime)
                implementation(compose.foundation)
                implementation(compose.material)
                @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
                implementation(compose.components.resources)
                implementation("io.ktor:ktor-client-core:$ktorVersion")
            }
        }

        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
            }
        }

        val iosX64Main by getting
        val iosArm64Main by getting
        val iosSimulatorArm64Main by getting
        val iosMain by creating {
            dependsOn(commonMain)
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosSimulatorArm64Main.dependsOn(this)

            dependencies {
                implementation("io.ktor:ktor-client-darwin:$ktorVersion")
            }
        }

        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
    }
}

android {
    namespace = "com.tippu.sheriff"
    compileSdk = 33
    defaultConfig {
        minSdk = 24
    }
}

Solution

  • It's because of this line targetHierarchy.default()

    When you use default target Hierarchy, it automatically adds some sourceSets based on the target you've set. Since you've added iOS targets iosX64(), iosArm64(), iosSimulatorArm64(), the plugin added iosMain based on that.

    Read more about it here in 1.9.20 docs. Note that you don't even need targetHierarchy.default() with 1.9.20. This feature is now enabled by default in latest version.

    Replace you code with this and it should most likely work,

    val iosMain by getting {
        dependencies {
            implementation("io.ktor:ktor-client-darwin:$ktorVersion")
        }
    }