This document describes the steps to migrate from klutter 2023.3.1.beta to 2024.1.3.beta. The most notable changes coming from 2023.3.1.beta are:
- Kradle is now a native executable.
- Support for Kotlin 1.9.x.
- Support for protobuf.
The migration steps mostly consist of updating dependencies and adjusting configuration layouts to conform to new standards.
Klutter 2024.1.3.beta is compatible with the following pub dependencies:
Update the ./pubspec.yaml to use these dependencies.
#.... omitted for brevity
environment:
sdk: '>=2.16.1 <3.0.0'
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
squint_json: ^0.1.2
klutter_ui: ^1.1.0
dev_dependencies:
klutter: ^3.0.2
Update ./example/pubspec.yaml as well:
...
#.... omitted for brevity
dependencies:
#.... omitted for brevity
klutter_ui: ^1.1.0
squint_json: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
klutter: ^3.0.2
- Root build.gradle.kts
- Platform build.gradle.kts
- Root Android build.gradle
- Update gradle.properties
- Example Android build.gradle
- Example Android App build.gradle
Update the classpath dependencies in the ./build.gradle.kts file.
buildscript {
repositories {
...
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10")
...
classpath(platform("dev.buijs.klutter:bom:2024.1.3.beta"))
...
}
}
Update the plugin.serialization version.
plugins {
...
kotlin("plugin.serialization") version "1.9.0"
}
Replace the deprecated android() method with androidTarget() and androidTest with androidUnitTest.
kotlin {
// replace android with androidTarget()
androidTarget()
...
// replace androidTest with androidUnitTest
val androidUnitTest by getting ...
}
Rename the root/platform/src/androidTest directory to root/platform/src/androidUnitTest.
Add publishing configuration to the android dsl.
android {
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
singleVariant("debug") {
withSourcesJar()
withJavadocJar()
}
}
}
At the end of the build.gradle.kts file add the following boilerplate code. This is required to run the protobuf tasks (when opting in for it).
val gradleBuildInstanceClassLoader: ClassLoader = this::class.java.classLoader
tasks.register<GenerateProtoSchemasGradleTask>(GenerateProtoSchemasGradleTask.taskName) {
classLoader = gradleBuildInstanceClassLoader
}
tasks.configureEach {
if (name.startsWith("compile")) {
mustRunAfter(tasks.named("kspCommonMainKotlinMetadata"))
}
}
Remove the following code from the build.gradle.kts file, because these tasks are now automatically added through the gradle plugin.
tasks.build.get()
.setFinalizedBy(listOf(
tasks.getByName("assemblePlatformReleaseXCFramework"),
tasks.getByName("klutterCopyAarFile")))
tasks.getByName("assemblePlatformReleaseXCFramework")
.setFinalizedBy(listOf(tasks.getByName("klutterCopyFramework")))
The final build.gradle.kts file should resemble the following:
import dev.buijs.klutter.gradle.dsl.embedded
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
import dev.buijs.klutter.gradle.tasks.*
plugins {
id("com.android.library")
id("dev.buijs.klutter")
kotlin("multiplatform")
kotlin("plugin.serialization") version "1.9.0"
}
version = "1.0"
klutter {
root = rootProject.rootDir
plugin {
name = //the name of the plugin
}
include("bill-of-materials")
}
kotlin {
jvmToolchain(17)
androidTarget()
val xcfName = "Platform"
val xcFramework = XCFramework(xcfName)
ios {
binaries.framework {
baseName = xcfName
xcFramework.add(this)
export("dev.buijs.klutter:flutter-engine:2024.1.1.beta")
}
}
iosSimulatorArm64 {
binaries.framework {
baseName = xcfName
xcFramework.add(this)
export("dev.buijs.klutter:flutter-engine-iosSimulatorArm64:2024.1.1.beta")
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
}
}
val androidMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
embedded("dev.buijs.klutter:flutter-engine-kmp-android:2024.1.1.beta")
}
}
val androidUnitTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
}
}
val iosMain by getting {
dependencies {
api("dev.buijs.klutter:flutter-engine:2024.1.1.beta")
}
}
val iosSimulatorArm64Main by getting {
dependsOn(iosMain)
dependencies {
api("dev.buijs.klutter:flutter-engine-iosSimulatorArm64:2024.1.1.beta")
}
}
val iosTest by getting
val iosSimulatorArm64Test by getting {
dependsOn(iosTest)
}
}
}
android {
namespace = //package of plugin + name of plugin + .platform e.g: "dev.buijs.klutter.cookbook.examples.hello_world.platform"
sourceSets["main"].kotlin { srcDirs("src/androidMain/kotlin") }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
defaultConfig {
compileSdk = 33
minSdk = 24
}
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
singleVariant("debug") {
withSourcesJar()
withJavadocJar()
}
}
}
val gradleBuildInstanceClassLoader: ClassLoader = this::class.java.classLoader
tasks.register<GenerateProtoSchemasGradleTask>(GenerateProtoSchemasGradleTask.taskName) {
classLoader = gradleBuildInstanceClassLoader
}
tasks.configureEach {
if (name.startsWith("compile")) {
mustRunAfter(tasks.named("kspCommonMainKotlinMetadata"))
}
}
In the android/build.gradle update the classpath dependencies.
buildscript {
...
dependencies {
classpath platform("dev.buijs.klutter:bom:2024.1.3.beta")
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10"
}
}
Remove the minSdkVersion and add minSdk.
android {
...
defaultConfig {
compileSdk 33
// remove minSdkVersion and add minSdk
minSdk 24
}
}
Update the dependencies.
dependencies {
runtimeOnly "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.10"
...
}
In the root/example/android/build.gradle file bump the kotlin-gradle-plugin version.
buildscript {
...
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10"
}
}
In the root/example/android/app/build.gradle file bump the kotlin dependency and add jvmToolchain.
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.10"
}
kotlin {
jvmToolchain(17)
}
Remove the following property from the gradle.properties in:
- root/android/gradle.properties
- root/gradle.properties
kotlin.mpp.enableCInteropCommonization=true
In the root/ios/.podspec bump the ios version to 13.
s.platform = :ios, '13.0'
In the root/ios/example/Podfile also bump the ios version to 13.
platform :ios, '13.0'
Delete the root/example/ios/Podfile.lock file and then run the following from the root/example/ios directory:
pod deintegrate
pod install
pod update
Delete all content from the root/.kradle directory.
Create a kradle.env file in the root directory with the following content:
cache={{system.user.home}}/.kradle/cache/
output.path={{project.build}}/klutter
skip.codegen=false
protoc.url=https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-osx-universal_binary.zip
Update the kradle.yaml file with the following content:
bom-version: "2024.1.3.beta"
flutter-version: "3.10.6" #or other compatible version
feature-protobuf-enabled: false
dependencies:
klutter: "3.0.2"
klutter_ui: "1.1.0"
squint_json: "0.1.2"
embedded:
- "dev.buijs.klutter:flutter-engine-kmp-android:2024.1.1.beta"
Reload the gradle project and then run:
./gradlew klutterGetKradle
This will create a native executable for the kradle tool in the root of the project. Build the project by running a kradle build and then run the app on your device.
./kradle build
Or use the interactive mode:
./kradle