Search code examples
androidgradleandroid-roomkotlin-multiplatform

What gradle entries are required for implementing KSP and Room in a Kotlin Multiplatform


I am in the process of converting a kotlin application to kotlin multiplatform (anroid only for now to get through initial configuration) with room. This included moving to a libs.versions.toml file and KSP.

When compiling the app, I get the following error.

Any assistance you can provide would be greatly appreciated.

Build file 'C:\Users\georg\AndroidStudioProjects\PeepsConnection\build.gradle.kts' line: 26

Plugin [id: 'com.google.devtools.ksp', version: '2.6.1', apply: false] was not found in any of the following sources:

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

* Exception is:
org.gradle.api.plugins.UnknownPluginException: Plugin [id: 'com.google.devtools.ksp', version: '2.6.1', apply: false] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Included Builds (No included builds contain this plugin)
- Plugin Repositories (could not resolve plugin artifact 'com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.6.1')
  Searched in the following repositories:
    Google
    MavenRepo
    flatDir(C:\Users\georg\AndroidStudioProjects\PeepsConnection\libs)
    maven(https://plugins.gradle.org/m2/)
    at 
---------------- lines left out to fit in question size limit ---------- 

The following is my libs.version.toml file

[versions]
kotlinVersion = "2.0.0"
roomVersion = "2.6.1"
lifecycleVersion = "2.8.3"
materialVersion = "1.12.0"
recyclerviewVersion = "1.3.2"
playServicesAdsVersion =  "23.2.0"
playServicesGCMVersion =  "17.0.0"
firebaseAdsVersion = "23.2.0"
workRuntimeVersion =  "2.9.0"
preferenceKTXVersion  = "1.2.1"
playServicesMapsVersion = "19.0.0"
firebaseAuthVersion = "23.0.0"
annotationVersion = "1.8.0"
lifecycleLiveDataKTXVersion = "2.8.3"
lifecycleViewModelKTXVersion = "2.8.3"
firebaseDatabaseVersion = "21.0.0"
firebaseFunctionsVersion =  "21.0.0"
wearVersion = "1.3.0"
viewpager2Version = "1.1.0"
touchImageViewVersion = "1.4.1"
firebaseBOMVersion = "33.1.2"
firebaseAnalyticsVersion = "22.0.2"
firebaseMessagingVersion = "24.0.0"
firebaseAppcheckVersion = "18.0.0"
firebaseUIDatabasse = "8.0.2"
firebaseUIAuth = "8.0.2"
volleyVersion = "1.2.1"
playServicesLocationVersion = "21.3.0"
multidexVersion = "2.0.1"
mapsVersion = "3.1.0-beta"
biometricVersion = "1.2.0-alpha05"
autoValueAnnotationsVersion = "1.10.4"
androidMapsUtilsVersion = "3.8.2"
gsonVersion = "2.10.1"
androidMapsExtensionVersion =  "2.4.0"
workRuntimeKTXVersion = "2.9.0"
roomRuntimeVersion = "2.6.1"
roomGradlePluginVersion = "2.6.1"
sqliteKTXVeresion  = "2.4.0"
androidDdatabaseSqlcipherVersion = "4.5.3"
sqlcipherAndroidVersion = "4.5.5@aar"
vannitechVersion = "com0.7.0"
devToolsKSPVersion = "2.6.1"
androidRoomVersion = "2.6.1"
googleServicesVersion = "4.4.2"
androidGradlePluginVersion = "7.4.2"
kotlinMultiplatformVersion = "2.0.0"

[libraries]

androidx-recyclerview = {group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerviewVersion"}
com-vannitech = {group = "com.vanniktech", name = "emoji-google", version.ref = "vannitechVersion"}
com-google-android-gms-play-services-ads = {group = "com.google.android.gms", name = "play-services-ads", version.ref = "playServicesAdsVersion"}
com-google-firebase-firebase-ads = {group = "com.google.firebase", name = "firebase-ads", version.ref = "firebaseAdsVersion"}
androidx-work-work-runtime = {group = "androidx.work", name = "work-runtime", version.ref = "workRuntimeVersion"}
androidx-preference-preference-ktx = {group = "androidx.preference", name = "preference-ktx", version.ref = "preferenceKTXVersion"}
com-google-android-gms-play-services-maps = {group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMapsVersion"}
com-google-firebase-firebase-auth = {group = "com.google.firebase", name = "firebase-auth", version.ref = "firebaseAuthVersion"}
androidx-annotation = {group = "androidx.annotation", name = "annotation", version.ref = "annotationVersion"}
androidx-lifecycle-lifecycle-livedata-ktx = {group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLiveDataKTXVersion"}
androidx-lifecycle-lifecycle-viewmodel-ktx = {group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelKTXVersion"}
com-google-firebase-firebase-database = {group = "com.google.firebase", name = "firebase-database", version.ref = "firebaseDatabaseVersion"}
com-google-firebase-firebase-functions = {group = "com.google.firebase", name = "firebase-functions", version.ref = "firebaseFunctionsVersion"}
androidx-wear = {group = "androidx.wear", name = "wear", version.ref = "wearVersion"}
androidx-viewpager = {group = "androidx.viewpager2", name = "viewpager2", version.ref = "viewpager2Version"}
com-github-MikeOrtiz = {group = "com.github.MikeOrtiz", name = "TouchImageView", version.ref = "touchImageViewVersion"}
com-google-firebase-firebase-bom = {group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBOMVersion"}
com-google-firebase-firebase-analytics = {group = "com.google.firebase", name = "firebase-analytics", version.ref = "firebaseAnalyticsVersion"}
com-google-firebase-firebase-messaging = {group = "com.google.firebase", name = "firebase-messaging", version.ref = "firebaseMessagingVersion"}
com-google-firebase-firebase-appcheck-debug = {group = "com.google.firebase", name = "firebase-appcheck-debug", version.ref = "firebaseAppcheckVersion"}
com-google-firebase-firebase-appcheck-playintegrity = {group = "com.google.firebase", name = "firebase-appcheck-playintegrity", version.ref = "firebaseAppcheckVersion"}
com-firebaseui-firebase-ui-database = {group = "com.firebaseui", name = "firebase-ui-database", version.ref = "firebaseUIDatabasse"}
com-firebaseui-firebase-ui-auth = {group = "com.firebaseui", name = "firebase-ui-auth", version.ref = "firebaseUIAuth"}
com-google-android-material-material = {group = "com.google.android.material", name = "material", version.ref = "materialVersion"}
com-google-gms-play-services-gcm = {group = "com.google.android.gms", name = "play-services-gcm", version.ref = "playServicesGCMVersion"}
com-android-volley = {group = "com.android.volley", name = "volley", version.ref = "volleyVersion"}
com-google-android-gms = {group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocationVersion"}
androidx-mutidex = {group = "androidx.multidex", name = "multidex", version.ref = "multidexVersion"}
com-google-android-libraries-maps = {group = "com.google.android.libraries.maps", name = "maps", version.ref = "mapsVersion"}
androidx-biometrics = {group = "androidx.biometric", name = "biometric", version.ref = "biometricVersion"}
com-google-auto-value-annotations = {group = "com.google.auto.value", name = "auto-value-annotations", version.ref = "autoValueAnnotationsVersion"}
com-google-maps-android = {group = "com.google.maps.android", name = "android-maps-utils", version.ref = "androidMapsUtilsVersion"}
com-google-code-json = {group = "com.google.code.gson", name = "gson", version.ref = "gsonVersion"}
com-anroidmapsextension = {group = "com.androidmapsextensions", name = "android-maps-extensions", version.ref = "androidMapsExtensionVersion"}
androidx-work = {group = "androidx.work", name = "work-runtime-ktx", version.ref = "workRuntimeKTXVersion"}
androidx-room-room-gradle-plugin = {group = "androidx.room", name = "room-gradle-plugin", version.ref = "roomGradlePluginVersion"}
androidx-room-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomVersion" }
androidx-room-room-runtime = {group = "androidx.room", name = "room-runtime", version.ref = "roomRuntimeVersion"}
androidx-room-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "devToolsKSPVersion" }
androidx-sqlite = {group = "androidx.sqlite", name = "sqlite-ktx", version.ref = "sqliteKTXVeresion"}
net-zetic-android-database-sqlcipher = {group = "net.zetetic", name = "android-database-sqlcipher", version.ref = "androidDdatabaseSqlcipherVersion"}
net-zetic-sqlcipher-android  = {group = "net.zetetic", name = "sqlcipher-android", version.ref = "sqlcipherAndroidVersion"}
androidx-lifecycle = {group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleVersion"}
com-google-devtools-ksp-gradle-plugin = {group = "com.google.devtools.ksp", name = "gradle-plugin",version.ref = "devToolsKSPVersion"}
kotlin-multiplatform = {group = "kotlin", name = "multiplatform", version.ref = "kotlinMultiplatformVersion"}
com-google-gms-google-services = {group = "com.google.gms", name = "google-services", version.ref = "googleServicesVersion"}

[plugins]
com-google-devtools-ksp = {id = "com.google.devtools.ksp",  version.ref =  "devToolsKSPVersion" }
org-jetbrains-kotlin-android = {id = "org.jetbrains.kotlin.android", version.ref =  "kotlinVersion"}
androidx-room = {id = "androidx.room", version.ref = "androidRoomVersion"}
kotlin-multiplatform = {id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlinMultiplatformVersion"}
com-android-application = {id =  "com.android.application", version.ref = "androidGradlePluginVersion"}
com-google-gms-google-services = {id = "com.google.gms.google.services", version.ref = "googleServicesVersion"}

The following is my project level build.gradle

buildscript {
    val kotlin_version = "2.0.0"
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
        maven {
            url = uri("https://www.jitpack.io")
            url = uri("https://plugins.gradle.org/m2/")
        }
        flatDir {
            dirs("libs")
        }
    }
    dependencies {
        classpath("com.android.tools.build:gradle:8.5.1")
        classpath("com.google.gms:google-services:4.4.2")
        classpath("com.google.devtools:ksp:2.6.1")
        classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:2.6.1")
        classpath("org.jetbrains.kotlin:kotlin-serialization:2.0.0")
    }

}

plugins {

    alias(libs.plugins.com.android.application) apply false
    alias(libs.plugins.org.jetbrains.kotlin.android)  apply false
    alias(libs.plugins.androidx.room) apply false
    alias(libs.plugins.kotlin.multiplatform) apply false
    alias(libs.plugins.com.google.devtools.ksp) apply false
}

allprojects {
    repositories {
        google()
        mavenCentral()
        configurations.configureEach {
            maven {
                url = uri("https://plugins.gradle.org/m2/")
                url = uri("https://www.jitpack.io" )
            }
            resolutionStrategy{
                force ("com.google.android.gms:play-services-location:20.0.0")
            }
        }

    }
}

The following is my app level build.gradle file

plugins {
    alias(libs.plugins.kotlin.multiplatform)
    alias(libs.plugins.com.android.application)
    alias(libs.plugins.com.google.gms.google.services)
    alias(libs.plugins.com.google.devtools.ksp)
    alias(libs.plugins.androidx.room)


}
var work_version = "2.9.0"

android {
    compileSdkVersion(34)
    defaultConfig {
        applicationId("com.grgmobilesolutions.peepsconnection")
        minSdkVersion(34)
        targetSdkVersion(34)
        versionCode(3)
        versionName("Beta 3.0.1")
        multiDexEnabled(true)
        testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner")
    }
    buildTypes {
        getByName("release") {
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        customDebugType {
            debuggable = true
        }
    }
    room {
        schemaDirectory "$projectDir/schemas"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_20
        targetCompatibility = JavaVersion.VERSION_20

    }

    namespace 'com.grgmobilesolutions.peepsconnection'
    buildFeatures {
        buildConfig = true
    }

    kotlin {
        androidTarget()
        sourceSets {
            commonMain.dependencies {

                }
            androidMain.dependencies {
                    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
                    implementation "androidx.core:core-ktx:1.13.1"
                    implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
                    implementation "androidx.core:core-ktx:1.13.1"
                    implementation "androidx.compose.material3:material3:1.2.1"
                    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3"
                    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0"
                    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0"
                    implementation "androidx.work:work-runtime:$work_version"
                    implementation "com.bugfender.sdk:android:3.2.0"
                    implementation "com.google.firebase:firebase-appcheck-debug:18.0.0"
                    implementation "com.google.firebase:firebase-appcheck-playintegrity:18.0.0"
                    implementation "com.android.billingclient:billing:7.0.0"
                    implementation "androidx.work:work-multiprocess:$work_version"
                    implementation group: "org.locationtech.jts", name: "jts-core", version: "1.19.0"
                    implementation "androidx.appcompat:appcompat:1.7.0"
                    implementation "androidx.constraintlayout:constraintlayout:2.1.4"
                    implementation "com.google.android.material:material:1.12.0"
                    implementation "androidx.legacy:legacy-support-v4:1.0.0"
                    implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
                    implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
                    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
                    implementation "androidx.recyclerview:recyclerview:1.3.2"
                    implementation "com.vanniktech:emoji-google:0.7.0"
                    implementation "com.google.android.gms:play-services-ads:23.2.0"
                    implementation "com.google.firebase:firebase-ads:23.2.0"
                    implementation "androidx.work:work-runtime:2.9.0"
                    implementation "androidx.preference:preference-ktx:1.2.1"
                    implementation "com.google.android.gms:play-services-maps:19.0.0"
                    implementation "com.google.firebase:firebase-auth:23.0.0"
                    implementation "androidx.annotation:annotation:1.8.0"
                    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.3"
                    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3"
                    implementation "com.google.firebase:firebase-database:21.0.0"
                    implementation "com.google.firebase:firebase-functions:21.0.0"
                    implementation "androidx.wear:wear:1.3.0"
                    implementation "androidx.viewpager2:viewpager2:1.1.0"
                    implementation "com.github.MikeOrtiz:TouchImageView:1.4.1"

                    // last SupportLib version
                    implementation platform("com.google.firebase:firebase-bom:33.1.1")
                    implementation "com.google.firebase:firebase-analytics:22.0.2"
                    implementation "com.google.firebase:firebase-messaging:24.0.0"
                    implementation "com.firebaseui:firebase-ui-database:8.0.2"
                    implementation "com.firebaseui:firebase-ui-auth:8.0.2"
                    implementation "com.google.android.material:material:1.12.0"
                    implementation "com.google.android.gms:play-services-gcm:17.0.0"
                    implementation "com.android.volley:volley:1.2.1"
                    implementation "com.google.android.gms:play-services-location:21.3.0"
                    implementation "androidx.multidex:multidex:2.0.1"
                    implementation "com.google.android.libraries.maps:maps:3.1.0-beta"
                    implementation "androidx.biometric:biometric:1.2.0-alpha05"
                    implementation "com.google.auto.value:auto-value-annotations:1.10.4"
                    implementation "com.google.maps.android:android-maps-utils:3.8.2"
                    implementation "com.google.code.gson:gson:2.10.1"
                    implementation "com.androidmapsextensions:android-maps-extensions:2.4.0"
                    implementation("com.mikepenz:materialdrawer:5.9.5@aar") {
                        transitive = true
                        exclude group: "com.android.support"
                    }
                    implementation files("libs/activation.jar")
                    implementation files("libs/additionnal.jar")
                    implementation files("libs/mail.jar")
                    implementation("androidx.work:work-runtime-ktx:$work_version")

                    // Room components
                    implementation "androidx.room:room-runtime:2.6.1"
                    //annotationProcessor "androidx.room:room-compiler:2.6.1"
                    ksp("androidx.room:room-compiler:2.6.1")
                    implementation "androidx.room:room-testing:2.6.1"
                    implementation "androidx.sqlite:sqlite-ktx:2.4.0"
                    implementation "net.zetetic:sqlcipher-android:4.5.5@aar"

                    // Lifecycle components
                    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
                    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
                    implementation "androidx.lifecycle:lifecycle-common-java8:2.8.3"
                    implementation "androidx.lifecycle:lifecycle-compiler:2.2.0"

                    // UI
                    implementation "com.google.android.material:material:1.12.0"

                    // Testing
                    implementation "androidx.arch.core:core-testing:2.2.0"

                    compileOnly "com.google.android.wearable:wearable:2.9.0"
                }
            }
        }
}

Solution

  • a) Have a look at the KSP quickstart tutorial. The version to use is a whole other:

    [versions]
    # devtools_ksp = "1.5.30-1.0.0"
    devtools_ksp = "2.0.0-1.0.23"
    
    [plugins]
    devtools_ksp = { id = "com.google.devtools.ksp", version.ref = "devtools_ksp" }
    

    b) Load it in the root-project build.gradle:

    plugins {
        alias(libs.plugins.devtools.ksp) apply false
    }
    

    b) Apply it in the module build.gradle:

    plugins {
        alias(libs.plugins.devtools.ksp)
    }
    

    d) For multiplatform, the dependencies need to be defined differently.

    kotlin {
        sourceSets {
            commonMain.dependencies {
                ksp("androidx.room:room-compiler:2.7.0-alpha01")
            }
            androidMain.dependencies {}
            iosMain.dependencies {}
        }
    }
    

    e) The schema location also needs to be defined differently:

    ksp {
         arg("room.schemaLocation", "$projectDir/schemas")
    }
    

    f) In file settings.gradle, add this line:

    kotlin.native.disableCompilerDaemon = true
    

    See Room (Kotlin Multiplatform) for details; there's now also a bundled SQLite library for iOS.

    And there's also a Migrate Room to Kotlin Multiplatform tutorial.