Does anyone know how to make an XCFramework build ...
# multiplatform
c
Does anyone know how to make an XCFramework build that works for iosArm32 as well as iosArm64 and iosX64? I have my xcframework build working great with iosArm64 and iosX64 together, but when I try to add in iosArm32 I get a build error of "KotlinTarget with name 'iosArm32 not found"
Copy code
val buildXcFramework by tasks.registering {
    dependsOn("deleteXcFramework")
    group = "build"
    val mode = "Release"
    val frameworks = arrayOf("iosArm64", "iosX64", "iosArm32")
        .map { kotlin.targets.getByName<KotlinNativeTarget>(it).binaries.getFramework(mode) }
    inputs.property("mode", mode)
    dependsOn(frameworks.map { it.linkTask })
    doLast { buildXcFramework(frameworks) }
}
t
Have you explicitly added iosArm32 support to your project? If you are just using the
ios
shortcut it doesn't add it
c
Thank you I think you are correct that I missed that. I just now tried to add it but I think I'm doing it incorrectly because now I get an error: KotlinSourceSet with name 'iosArm32Main' not found. Does this look correct?
Copy code
val iosX64Main by sourceSets.getting
val iosArm64Main by sourceSets.getting
val iosArm32Main by sourceSets.getting

val iosMain by sourceSets.creating {
    dependsOn(commonMain)
    iosX64Main.dependsOn(this)
    iosArm64Main.dependsOn(this)
    iosArm32Main.dependsOn(this)
}
t
that looks like it should work, but iosMain might be a special case, you might name it something else as a test
that seems wrong based on the error
c
Gotcha, been trying some other things but still getting stuck on the KotlinSourceSet with name 'iosArm32Main' not found. I'll keep plugging away at, please let me know if you have any other suggestions to look in to.
t
I believe you need to add iosArm32 as a target first
So what you did above is to create the combined sourceSet so you can target the three sourceSets with one code target
but you didn't tell kotlin multiplatform to build for iosArm32
👍 1
once you add it as a top level platform you can then create the source set for them all
👀 1
c
Thanks that makes sense and gets me VERY close I think. I added it in:
Copy code
kotlin {
    val serializationVersion = "1.1.0"
    val koTestVersion = "4.4.3"

    android()

    iosArm32()

    ios {
        binaries {
            framework {
                baseName = "MBKMMShared"
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
                implementation("io.kotest:kotest-property:$koTestVersion")
                implementation("io.kotest:kotest-assertions-core:$koTestVersion")
            }
        }
        val androidMain by getting
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13")
            }
        }

        val iosTest by getting

        val iosX64Main by sourceSets.getting
        val iosArm64Main by sourceSets.getting
        val iosArm32Main by sourceSets.getting

        val iosMain by sourceSets.getting {
            dependsOn(commonMain)
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosArm32Main.dependsOn(this)
        }
    }
}
And I think that helped because on gradle sync I got this:
Task sharedrunCommonizer
Kotlin KLIB commonizer: Please wait while preparing libraries. [Step 1 of 1] Preparing commonized Kotlin/Native libraries for targets [ios_arm32], [ios_x64], [ios_arm64] (420 items) * Read lazy (uninitialized) libraries in 400ms * Loaded declarations for [ios_arm32] in 17s 450ms * Loaded declarations for [ios_x64] in 14s 387ms * Loaded declarations for [ios_arm64] in 13s 413ms * Commonized declarations in 1s 696ms * Prepared new descriptors in 3s 486ms * Written libraries for [ios_arm32(*), ios_x64, ios_arm64] in 11s 698ms * Written libraries for [ios_arm32, ios_x64(*), ios_arm64] in 9s 628ms * Written libraries for [ios_arm32, ios_x64, ios_arm64(*)] in 10s 816ms * Written libraries for [ios_arm32, ios_x64, ios_arm64] in 4s 716ms TOTAL: 1m 27s 690ms [Step 1 of 1] Preparing commonized Kotlin/Native libraries for targets [ios_arm32], [ios_x64], [ios_arm64] (420 items): Done
But when I try to run my task buildXcFramework I now get • java.util.NoSuchElementException: Key releaseFramework is missing in the map.  on the map line:
Copy code
.map { kotlin.targets.getByName<KotlinNativeTarget>(it).binaries.getFramework(mode) }
Copy code
val buildXcFramework by tasks.registering {
    dependsOn("deleteXcFramework")
    group = "build"
    val mode = "Release"
    val frameworks = arrayOf("iosArm64", "iosX64", "iosArm32")
        .map { kotlin.targets.getByName<KotlinNativeTarget>(it).binaries.getFramework(mode) }
    inputs.property("mode", mode)
    dependsOn(frameworks.map { it.linkTask })
    doLast { buildXcFramework(frameworks) }
}
104 Views