sqldelight icon indicating copy to clipboard operation
sqldelight copied to clipboard

IOS build application fails when using sqldelight native driver NativeSqliteDriver

Open PaytonGunnell opened this issue 1 year ago • 7 comments

SQLDelight Version

2.0.1

Operating System

macOS Sonoma 14.3

Gradle Version

8.4

Kotlin Version

1.9.22

Dialect

dont know

AGP Version

8.2.1

Describe the Bug

Im using kmm for android and ios multiplatform, I followed this tutorial for sqldelight and when I run the iosApp it crashes with this message:

The following build commands failed: Ld /build/ios/Debug-iphonesimulator/GreetingKMP.app/GreetingKMP normal (in target 'iosApp' from project 'iosApp') (1 failure)

I eventually figured out that if I change the iosMain actual class for DriverFactory:

actual class DriverFactory { actual fun createDriver(): SqlDriver { return NativeSqliteDriver(Database.Schema, "test.db") } }

to this:

actual class DriverFactory { actual fun createDriver(): SqlDriver { TODO() } }

the iosApp build will succeed. Here is a link to the project: https://github.com/PaytonGunnell/GreetingKMP Ive looked around and cant find any solutions, but here are some things I have already tried:

sqldelight: 2.0.1 -> 2.0.0 grade: 8.4 -> 8.2 gradle plugin: 8.2.0 -> 8.2.1 kotlin: 1.9.22 -> 1.9.20 simulator ios version: 17.2 -> 15.0

my kdoctor output: [✓] Operation System [✓] Java [✓] Android Studio [✓] Xcode [✓] CocoaPods

Conclusion: ✓ Your operation system is ready for Kotlin Multiplatform Mobile Development!

Stacktrace

No response

Gradle Build Script

plugins {
    id("org.jetbrains.kotlin.multiplatform").version("1.9.22")
    id("com.android.library").version("8.2.1")
    kotlin("plugin.serialization").version("1.9.22")
    id("com.google.devtools.ksp")
    id("com.rickclephas.kmp.nativecoroutines")
    id("app.cash.sqldelight").version("2.0.1")
}

sqldelight {
    databases {
        create("Database") {
            packageName.set("com.example")
        }
    }
}

kotlin {
    targets.all {
        compilations.all {
            compilerOptions.configure {
                freeCompilerArgs.add("-Xexpect-actual-classes")
            }
        }
    }
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }
    
    jvm()
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }
    
    sourceSets {
        val ktorVersion = "2.3.8"
        val sqldelightVersion = "2.0.1"

        all {
            languageSettings.optIn("kotlin.experimental.ExperimentalObjCName")
        }
        commonMain.dependencies {
            // Datetime
            implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")

            // Coroutines
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")

            // Ktor
            implementation("io.ktor:ktor-client-core:$ktorVersion")
            implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
            implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")

            // SQLDelight
            implementation("app.cash.sqldelight:runtime:$sqldelightVersion")

            // Koin
            implementation("io.insert-koin:koin-core:3.5.3")
            implementation("io.insert-koin:koin-test:3.5.3")
        }
        commonTest.dependencies {
            implementation("org.jetbrains.kotlin:kotlin-test:1.9.22")
        }
        androidMain.dependencies {
            // Ktor
            implementation("io.ktor:ktor-client-android:$ktorVersion")

            // SQLDelight
            implementation("app.cash.sqldelight:android-driver:$sqldelightVersion")
        }
        iosMain.dependencies {
            // Ktor
            implementation("io.ktor:ktor-client-darwin:$ktorVersion")

            // SQLDelight
            implementation("app.cash.sqldelight:native-driver:$sqldelightVersion")
        }
        jvmMain.dependencies {
            // SQLDelight
            implementation(libs.sqldelight.driver)
        }
    }
}

android {
    namespace = "com.example.greetingkmp.shared"
    compileSdk = libs.versions.android.compileSdk.get().toInt()
    defaultConfig {
        minSdk = libs.versions.android.minSdk.get().toInt()
    }
}

PaytonGunnell avatar Feb 05 '24 09:02 PaytonGunnell

I figured out that if you change in gradle isStatic = true to isSataic = false, the ios build will run.

build.gradle.kts (:shared):

android { ... listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach { iosTarget -> iosTarget.binaries.framework { baseName = "Shared"
isStatic = false // Changed from true -> false } } ... }

Is this a good solution or does this cause other problems? I dont know what changing isStatic does.

PaytonGunnell avatar Feb 05 '24 20:02 PaytonGunnell

I'm facing this issue too and the isStatic workaround worked for me as well.

john17727 avatar Feb 07 '24 02:02 john17727

I've also run into this issue, and changing isStatic to false solves it, bit I have no idea what that actually does or if it will cause other problems later on?

projectdelta6 avatar Mar 15 '24 09:03 projectdelta6

This work around solved the problem. No idea though..

aMujeeb avatar Mar 27 '24 06:03 aMujeeb

Still an issue on 2.0.2 on iOS, isStatic = false is a workaround, but I would not consider this a fix.

oblakr24 avatar Jun 15 '24 11:06 oblakr24

Check out this Turn off static linking

ikvarxt avatar Jun 30 '24 16:06 ikvarxt

Whenever I do this it fails with an exception while starting the app. Its not able to find the shared compiled kotlin library.

JulianBissekkou avatar Jul 01 '24 05:07 JulianBissekkou