Search code examples
kotlingradlekotlin-multiplatform

Cannot build release version of KMM app in iOS


I'm trying to build a release build for my KMM app on iOS. The progress fails with message
Exception in thread "main" java.lang.IllegalStateException: Could not find 'libCryptoKitWrapper.a' binary in neither of [CryptoKitWrapper/build/Release-iphoneos]
The exception traces to the Swift library I'm using. For it to work on kotlin I'm using this method. Surprisingly the file in question can be found in the listed directory. What might be the problem here? Related cinterop task:

iosTarget("ios") {
    val platform = when (preset?.name) {
        "iosX64" -> "iphonesimulator"
        "iosArm64" -> "iphoneos"
        else -> error("Unsupported target $name")
    }
    compilations.getByName("main") {
        cinterops.create("CryptoKitWrapper") {
            val interopTask = tasks[interopProcessingTaskName]
            interopTask.dependsOn(":CryptoKitWrapper:build${platform.capitalize()}")
            includeDirs.headerFilterOnly("$rootDir/CryptoKitWrapper/build/Release-$platform/include")
        }
    }
}

Solution

  • The problem is caused by the fact that the Gradle interprets locations set with libraryPaths as a relative path, deriving it from current OS directory. To observe this, try executing ./gradlew :shared:cinteropCryptoKitWrapperIos --info from SwiftLibSample dir, and ../gradlew cinteropCryptoKitWrapperIos --info from SwiftLibSample/shared. The first one should work correctly.

    To workaround the problem, one can do the following. Instead of hard-coding path to the .def file, set this parameter inside the cinterops{...} block. I tried this one, inspired by the @SalomonBRYS' answer at https://github.com/JetBrains/kotlin-native/issues/2314

    cinterops.create("CryptoKitWrapper") {
                    ...
                    extraOpts("-libraryPath", "$rootDir/CryptoKitWrapper/build/Release-$platform")
                    ...
    

    If you would like to receive updates on this problem, please follow this issue at the official Kotlin issue tracker KT-48082

    EDIT: The following does not directly relate to the original question, I just want to summarize my tips from the comment section below.

    To enable the bitcode used in the project layout as in https://github.com/MJegorovas/SwiftLibSample, one should:

    1. Make the static library contain the Bitcode. In this case, "BITCODE_GENERATION_MODE=bitcode" option should be across xcodebuild arguments.

    2. Make the cinterop tool link the library with the bitcode. Add -lto-embed-bitcode linker option to the .def file.