Using different Kotlin versions in a KMM project

Share on:

More and more Kotlin Multiplafrom projects are now using Jetpack Compose for the Android UI and with that comes the potential inconvenience that Compose (including recent stable version) still depends on Kotlin 1.5.10 while a number of libraries typically used in KMM projects (such as Kotlinx Serialization and Ktor) are now using Kotlin 1.5.21. This mismatch is not typically an issue for Android applications but for say iOS client (where shared code is built using Kotlin/Native) continuing to use 1.5.10 will causes binary incompatibility issues.

To work around this for now I’ve made following changes to a number of the KMM samples I have in GitHub, covering at least cases where project is using using eitherpackForXCode/embedAndSignAppleFrameworkForXcode or CocoaPods.

build.gradle.kts updates

In both cases I’ve updated the root build.gradle.kts to pull in new kotlinVersion gradle property which is set by default to kotlinVersion=1.5.10 in gradle.properties

buildscript {
    val kotlinVersion: String by project
    ...
	
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
        classpath("org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}")
    }
   ...
}

packForXCode/embedAndSignAppleFrameworkForXcode

This is the more straightforward update to make. We simply add -P"kotlinVersion"="1.5.21" to gradle command in XCode run script as shown below. Note that having done this we can actually now start to make use of new embedAndSignAppleFrameworkForXcode task added in Kotlin 1.5.20 (allowing the removal of the packForXCode task in build script for shared code).

XCode run script update

CocoaPods

We have less direct control over gradle command line options when using CocoaPods so for now am making use of approach recommended by Kurt Acosta below.


Having performed at least initial build we then add noPodspec() to cocoapods section in shared code build script, update the generated podspec file as shown below (adding -PkotlinVersion="1.5.21" \ line) and then re-run pod install.

  :script => <<-SCRIPT
      set -ev
      REPO_ROOT="$PODS_TARGET_SRCROOT"
      "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" :common:syncFramework \
          -PkotlinVersion="1.5.21" \
          -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET \
          -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \
          -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \
          -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \
          -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS"
  SCRIPT