Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin Multiplatform (iOS): not working with Cocoapods plugin #1442

Closed
LiewJunTung opened this issue Aug 21, 2019 · 37 comments
Closed

Kotlin Multiplatform (iOS): not working with Cocoapods plugin #1442

LiewJunTung opened this issue Aug 21, 2019 · 37 comments

Comments

@LiewJunTung
Copy link

Tried to use the kotlin native cocoapod gradle plugin. But it produces the error below whenever sqldelight is included as a dependency.

Undefined symbols for architecture arm64:
"_sqlite3_bind_text16", referenced from:
_SQLiter_SQLiteStatement_nativeBindString in app(combined.o)
"_sqlite3_bind_int64", referenced from:
_SQLiter_SQLiteStatement_nativeBindLong in app(combined.o)
"_sqlite3_last_insert_rowid", referenced from:
_SQLiter_SQLiteStatement_nativeExecuteForLastInsertedRowId in app(combined.o)
"_sqlite3_reset", referenced from:
_SQLiter_SQLiteConnection_nativeResetStatement in app(combined.o)
"_sqlite3_changes", referenced from:
_SQLiter_SQLiteStatement_nativeExecuteForChangedRowCount in app(combined.o)
_SQLiter_SQLiteStatement_nativeExecuteForLastInsertedRowId in app(combined.o)
"_sqlite3_open_v2", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_db_config", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_busy_timeout", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_trace", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_bind_parameter_index", referenced from:
_SQLiter_SQLiteConnection_nativeBindParameterIndex in app(combined.o)
"_sqlite3_column_bytes", referenced from:
_SQLiter_SQLiteConnection_nativeColumnGetString in app(combined.o)
_SQLiter_SQLiteConnection_nativeColumnGetBlob in app(combined.o)
"_sqlite3_finalize", referenced from:
_SQLiter_SQLiteStatement_nativeFinalizeStatement in app(combined.o)
"_sqlite3_column_text", referenced from:
_SQLiter_SQLiteConnection_nativeColumnGetString in app(combined.o)
"_sqlite3_column_name", referenced from:
_SQLiter_SQLiteConnection_nativeColumnName in app(combined.o)
"_sqlite3_bind_double", referenced from:
_SQLiter_SQLiteStatement_nativeBindDouble in app(combined.o)
"_sqlite3_profile", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_close", referenced from:
_SQLiter_SQLiteConnection_nativeClose in app(combined.o)
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_prepare16_v2", referenced from:
_SQLiter_SQLiteConnection_nativePrepareStatement in app(combined.o)
"_sqlite3_column_type", referenced from:
_SQLiter_SQLiteConnection_nativeColumnIsNull in app(combined.o)
_SQLiter_SQLiteConnection_nativeColumnType in app(combined.o)
"_sqlite3_column_count", referenced from:
_SQLiter_SQLiteConnection_nativeColumnCount in app(combined.o)
"_sqlite3_bind_blob", referenced from:
_SQLiter_SQLiteStatement_nativeBindBlob in app(combined.o)
"_sqlite3_db_readonly", referenced from:
_SQLiter_SQLiteConnection_nativeOpen in app(combined.o)
"_sqlite3_column_int64", referenced from:
_SQLiter_SQLiteConnection_nativeColumnGetLong in app(combined.o)
"_sqlite3_bind_null", referenced from:
_SQLiter_SQLiteStatement_nativeBindNull in app(combined.o)
"_sqlite3_extended_errcode", referenced from:
android::throw_sqlite3_exception(sqlite3*) in app(combined.o)
android::throw_sqlite3_exception(sqlite3*, char const*) in app(combined.o)
"_sqlite3_column_double", referenced from:
_SQLiter_SQLiteConnection_nativeColumnGetDouble in app(combined.o)
"_sqlite3_column_blob", referenced from:
_SQLiter_SQLiteConnection_nativeColumnGetBlob in app(combined.o)
"_sqlite3_step", referenced from:
_SQLiter_SQLiteConnection_nativeStep in app(combined.o)
_SQLiter_SQLiteStatement_nativeExecute in app(combined.o)
_SQLiter_SQLiteStatement_nativeExecuteForChangedRowCount in app(combined.o)
_SQLiter_SQLiteStatement_nativeExecuteForLastInsertedRowId in app(combined.o)
"_sqlite3_clear_bindings", referenced from:
_SQLiter_SQLiteConnection_nativeClearBindings in app(combined.o)
"_sqlite3_errmsg", referenced from:
android::throw_sqlite3_exception(sqlite3*) in app(combined.o)
android::throw_sqlite3_exception(sqlite3*, char const*) in app(combined.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@kpgalligan
Copy link
Collaborator

In xcode, you need to add -lsqlite3 to Other Liker Flags in your Bulid Settings. I generally get that from other included Pods, but it depends what you're using.

image

@alfdev
Copy link

alfdev commented Dec 28, 2019

Hi,

i have the same problem when build with gradlew assemble, any suggestion?
thanks

@kpgalligan
Copy link
Collaborator

Stack trace?

@alfdev
Copy link

alfdev commented Dec 29, 2019

Undefined symbols for architecture x86_64: "_sqlite3_bind_blob", referenced from: _SQLiter_SQLiteStatement_nativeBindBlob in result.o "_sqlite3_bind_double", referenced from: _SQLiter_SQLiteStatement_nativeBindDouble in result.o "_sqlite3_bind_int64", referenced from: _SQLiter_SQLiteStatement_nativeBindLong in result.o "_sqlite3_bind_null", referenced from: _SQLiter_SQLiteStatement_nativeBindNull in result.o "_sqlite3_bind_parameter_index", referenced from: _SQLiter_SQLiteConnection_nativeBindParameterIndex in result.o "_sqlite3_bind_text16", referenced from: _SQLiter_SQLiteStatement_nativeBindString in result.o "_sqlite3_busy_timeout", referenced from: _SQLiter_SQLiteConnection_nativeOpen in result.o "_sqlite3_changes", referenced from: _SQLiter_SQLiteStatement_nativeExecuteForChangedRowCount in result.o _SQLiter_SQLiteStatement_nativeExecuteForLastInsertedRowId in result.o "_sqlite3_clear_bindings", referenced from: _SQLiter_SQLiteConnection_nativeClearBindings in result.o "_sqlite3_close", referenced from: _SQLiter_SQLiteConnection_nativeClose in result.o _SQLiter_SQLiteConnection_nativeOpen in result.o "_sqlite3_column_blob", referenced from: _SQLiter_SQLiteConnection_nativeColumnGetBlob in result.o "_sqlite3_column_bytes", referenced from: _SQLiter_SQLiteConnection_nativeColumnGetString in result.o _SQLiter_SQLiteConnection_nativeColumnGetBlob in result.o "_sqlite3_column_count", referenced from: _SQLiter_SQLiteConnection_nativeColumnCount in result.o "_sqlite3_column_double", referenced from: _SQLiter_SQLiteConnection_nativeColumnGetDouble in result.o "_sqlite3_column_int64", referenced from: _SQLiter_SQLiteConnection_nativeColumnGetLong in result.o .. .. "_sqlite3_step", referenced from: _SQLiter_SQLiteConnection_nativeStep in result.o _SQLiter_SQLiteStatement_nativeExecute in result.o _SQLiter_SQLiteStatement_nativeExecuteForChangedRowCount in result.o _SQLiter_SQLiteStatement_nativeExecuteForLastInsertedRowId in result.o "_sqlite3_trace", referenced from: _SQLiter_SQLiteConnection_nativeOpen in result.o ld: symbol(s) not found for architecture x86_64 e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

@alfdev
Copy link

alfdev commented Dec 29, 2019

In the gradle i have:

        compilations.each {
            it.extraOpts("-linker-options", "-lsqlite3")
        }

@RudolfHladik
Copy link

@alfdev where exactly do you have it? do you have some example?

@HFabi
Copy link

HFabi commented Mar 29, 2020

I have the same problem when I use the Cocoapods plugin. The workaround from kpgalligan (setting the linker options in Xcode) is working but setting the linker options in gradle seems to have no effect.

Am I doing something wrong here?

val isDevice = System.getenv("SDK_NAME")?.startsWith("iphoneos") == true
if (isDevice)
  iosArm64("ios")
else
  iosX64("ios")

targets.getByName<KotlinNativeTarget>("ios").compilations.forEach {
  it.kotlinOptions.freeCompilerArgs += arrayOf("-linker-options", "-lsqlite3")
}

Also I found this issue JetBrains/kotlin-native#3672 . Does anyone know if “extraOpts” or “compilerArgs” work with the Cocoapods plugin in general ?

@kpgalligan
Copy link
Collaborator

kpgalligan commented Mar 29, 2020 via email

@j4GGy
Copy link

j4GGy commented Mar 30, 2020

@HFabi I ran into the same issue although I'm not using the Cocoapods plugin but the packForXCode gradle taks as in the Kotlin MPP for Android-iOS example and then linking the produced framework directly in Xcode. I was able to fix the issue by adding the linker options as follows:

OSTarget("ios") {
        binaries {
            framework {
                baseName = "sharedDatabase"
                linkerOpts.add("-lsqlite3")
            }
        }
    }

Maybe adding the linker options to the binaries may help in your case, too.

targets.getByName<KotlinNativeTarget>("ios").binaries.forEach {
        it.linkerOpts.add("-lsqlite3")
}

@Yeeeeeeah
Copy link

Yeeeeeeah commented Apr 1, 2020

@HFabi I ran into the same issue although I'm not using the Cocoapods plugin but the packForXCode gradle taks as in the Kotlin MPP for Android-iOS example and then linking the produced framework directly in Xcode. I was able to fix the issue by adding the linker options as follows:

OSTarget("ios") {
        binaries {
            framework {
                baseName = "sharedDatabase"
                linkerOpts.add("-lsqlite3")
            }
        }
    }

Maybe adding the linker options to the binaries may help in your case, too.

targets.getByName<KotlinNativeTarget>("ios").binaries.forEach {
        it.linkerOpts.add("-lsqlite3")
}

Hello, I try to add linkerOpts.add("-lsqlite3")
But I have this problem :
> Could not get unknown property 'linkerOpts' for object of type org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer.

This is my build.gradle :

    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") ? presets.iosArm64 : presets.iosX64
        fromPreset(iOSTarget, 'ios') {
            binaries {
                framework('iosFramework') // nom du framework
            }
        }
    }

@HFabi
Copy link

HFabi commented Apr 5, 2020

@Yeeeeeeah before I switched to the cocoapods plugin, I also used the packForXCode approach from the tutorial. There I could set linkSqlite = true, perhaps that solves your problem.

// build.gradle.kts
sqldelight {
  database("...") {
  // ...
  }
  linkSqlite = true  // <-
}

@luca992
Copy link
Contributor

luca992 commented Apr 19, 2020

Adding -lsqlite3 to Other Liker Flags in your Bulid Settings like @kpgalligan suggested worked for me.
But I also got it working with the cocoapods plugin using a dynamic library with the linker option added:

    targets.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>().forEach{
        it.binaries.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.Framework>()
            .forEach { lib ->
                lib.isStatic = false
                lib.linkerOpts.add("-lsqlite3")
            }
    }

Referenced:
JetBrains/kotlin-native#3059 (comment)

@trancongdanh
Copy link

@Yeeeeeeah before I switched to the cocoapods plugin, I also used the packForXCode approach from the tutorial. There I could set linkSqlite = true, perhaps that solves your problem.

// build.gradle.kts
sqldelight {
  database("...") {
  // ...
  }
  linkSqlite = true  // <-
}

Thank you very much. It helped me very much.

@atonamy
Copy link

atonamy commented Aug 15, 2021

Adding -lsqlite3 to Other Liker Flags in your Bulid Settings like @kpgalligan suggested worked for me.
But I also got it working with the cocoapods plugin using a dynamic library with the linker option added:

    targets.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>().forEach{
        it.binaries.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.Framework>()
            .forEach { lib ->
                lib.isStatic = false
                lib.linkerOpts.add("-lsqlite3")
            }
    }

Referenced:
JetBrains/kotlin-native#3059 (comment)

Not working :(
I having this error if I apply your snippets

 dyld: Library not loaded: @rpath/shared.framework/shared
  Referenced from: /Users/xxx/Library/Developer/CoreSimulator/Devices/C45D96EE-5100-44C1-BF8D-B78342FDE4AA/data/Containers/Bundle/Application/221A60F3-33D8-465B-B627-29C1EDA3D82A/iosApp.app/iosApp
  Reason: image not found

The only working solution is -lsqlite3 flag in Other Liker Flags of Xcode which is suggested by @kpgalligan

@kpgalligan
Copy link
Collaborator

kpgalligan commented Feb 22, 2022

This is kind of old, but the above message isn't really correct. This error:

 dyld: Library not loaded: @rpath/shared.framework/shared
  Referenced from: /Users/xxx/Library/Developer/CoreSimulator/Devices/C45D96EE-5100-44C1-BF8D-B78342FDE4AA/data/Containers/Bundle/Application/221A60F3-33D8-465B-B627-29C1EDA3D82A/iosApp.app/iosApp
  Reason: image not found

is totally unrelated. This happens occasionally when running a fresh build of a Kotlin framework built with the cocoapods plugin. You essentially need to run pod install again, then build the Kotlin again, and it should work.

Here's the summary as best I can explain it.

The sqldelight driver needs to have an instance of the sqlite library to link against for everything to work. A version ships with iOS, and you can use that by adding -lsqlite3 to the linker args. As stated above, you may need to do that in your kotlin config (generally for tests), or if you're building a dynamic framework, you can let sqldelight add it. It's been a while, but I'm pretty sure dynamic frameworks carry their linker args, static do not.

I will add to the statement above that we almost always use static frameworks. There are reasons why they tend to be the better option, so I wouldn't pick dynamic frameworks just because you can avoid -lsqlite3 :)

I think the confusion here is more around how iOS (or most native builds) link to things. It's just kind of different than what we might be used to in the JVM.

There are benefits. If you want to use SQLCIpher in your production build, but regular sqlite in your test build(s), that's pretty easy to support. You just link to one or the other when it's time to output a binary. That's kind of beyond the scope for today, but doable (you can also ship your own builds of sqlite from source. Android, on the other hand, makes this more complicated as you also need to maintain and ship an implementation of the driver, but I digress).

TL;DR linking to the sqlite3 library isn't a workaround. It's just one of the things you need to do. In some contexts, it happens automatically, and in others explicitly, but if you're hitting sqlite on iOS, the linking happened somewhere.

@rohitpawar2811
Copy link

hello can anyone make a just an registration page and Connect with database and when data inserted it shows in List-View
by Using KMM ,its urgent [email protected]

@kpgalligan
Copy link
Collaborator

@Rohit-pawar902 Are you asking for a sample app using Kotlin native? There are many. Ours: https://github.com/touchlab/KaMPKit

@ArtRoman
Copy link

I've got Undefined symbols for architecture arm64: error on SwiftUI previews on M1, spent hours on this. Solution was found in #2512

@mobinyardim
Copy link

@ArtRoman thank you after 2 days of struggle it works for me 👌🏻👌🏻

@Shahroz16
Copy link

@ArtRoman
I am not using coco-pods but rather SPM and I am still not able to get my preview working. Even though I have added isStatic = false

cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "14.1"
        framework {
            baseName = "shared"
            isStatic = false
        }
    }

 targets.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>()
            .forEach {
                it.binaries.filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.Framework>()
                    .forEach { lib ->
                        lib.isStatic = false
                        lib.linkerOpts.add("-lsqlite3")
                    }
            }

any insights what might be the problem? getting this error

 HumanReadableSwiftError
    
    SettingsError: noExecutablePath(<IDESwiftPackageStaticLibraryProductBuildable:ObjectIdentifier(0x00006000005a18c0):'shared'>)
    ```

@ArtRoman
Copy link

@ArtRoman I am not using coco-pods but rather SPM and I am still not able to get my preview working. Even though I have added isStatic = false

cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "14.1"
        framework {
            baseName = "shared"
            isStatic = false
        }
    }

Try to use the full format:

cocoapods {
    …
    framework((Action) {
        it.isStatic = false
    })
}

@kpgalligan
Copy link
Collaborator

kpgalligan commented Oct 29, 2022

Swift UI previews, AFAIK, require dynamic frameworks. That has nothing to do with the sqlite linking errors. SPM support in KMP doesn't carry along the linking params.

I believe making the framework dynamic (isStatic = false) inadvertently "fixed" the sqlite linking issue because dynamic frameworks also carry along some extra linking info that static frameworks do not. The sqldelight Gradle plugin silently adds -lsqlite3, and dynamic frameworks carry that along.

Again, when you see:

Undefined symbols for architecture arm64:
"_sqlite3_bind_text16", referenced from:
// etc

It's a linking issue, and it means you need -lsqlite3 somewhere.

I ran into this exact problem, live, less than a week ago: https://youtu.be/CIZU_NNAZsA?t=5665

As you can see in the video (if you maximize it, the text is small), you go into Xcode settings for your target, find "Other linker flags" and add -lsqlite3.

See this horribly compressed screenshot:

Screen Shot 2022-10-29 at 4 34 51 PM

Again, whenever you see Undefined symbols for architecture (whatever) followed by "_sqlite3_(something something)", referenced from:, that always means you need -lsqlite3 in your linker settings, and you do not have it.

Update: I have since confirmed, if you have a static framework, you need to add -lsqlite3 to your linker flags directly in Xcode. You can just use dynamic frameworks, but for a number of reasons I would generally suggest static, but that's a choice everybody needs to make for themselves...

@Shahroz16
Copy link

@kpgalligan adding the -lsqlite3 linker flag was my first action too, but unfortunately, this hasn't fixed my preview issues.

I am now inclining towards, maybe it's an Xcode issue with Swift preview, regardless of Static or Dynamic framework, SwiftUI just breaks with KMM.

Don't think it's down to SQL even anymore, its just any other framework causes preview to fail

@kpgalligan
Copy link
Collaborator

For SwiftUI previews, I'm told you need dynamic frameworks, although I'd definitely say I'm no expert there. If you use SQLDelight and a dynamic framework from Kotlin, you shouldn't need to add -lsqlite3 as SQLDelight adds it to the build, and the dynamic framework carries that along. At least in prod builds, I'd say static frameworks are generally better, but if you can't do SwiftUI previews in dev with static, then in dev certainly you'll want dynamic. It's kind of a toss up on which type to use, really, but besides the SwiftUI previews, I find most of the benefits to be in favor of static.

@charlee-dev
Copy link

I just had this issue in the new project I started, and all I had to do was what Kevin said, add -lsqlite3 in Other Linker Flags in the Xcode 🍺

@terrakok
Copy link

@kpgalligan
FYI since Kotlin 1.8.0 kotlin frameworks produced by cocoapods plugin is dynamic by default: https://kotlinlang.org/docs/whatsnew18.html#dynamic-frameworks-by-default-in-the-cocoapods-gradle-plugin

You can set up it as static if you know what it means under the hood. But the recommended way is to pass linker flags to the compiler in an ios app build setting.

@whataa
Copy link

whataa commented Jul 9, 2023

Add sqlite3 to your iosApp's podfile:

target 'iosApp' do
  pod 'sqlite3', '~> 3.42.0' // choose your version
end

If you encounter the following problems:

ld: file not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a

Change your IPHONEOS_DEPLOYMENT_TARGET to at least 9.0, for example:

# iosApp's podfile
post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.1'
        end
    end
end

@charlee-dev
Copy link

charlee-dev commented Jul 9, 2023

Or add it to your ios target:

    ios {
        binaries.framework {
            baseName = project.name

            compilations.all {
                kotlinOptions.freeCompilerArgs += arrayOf("-linker-options", "-lsqlite3")
            }
        }
    }

@neelratanguria
Copy link

Solution mentioned here worked for me:

https://stackoverflow.com/questions/31363714/undefined-symbols-for-architecture-i386-using-libsqlite3-dylib-with-fmdb-xcode-7

I added libsqlite3.tbd in the Target Setting->Build Phase->Link Binary with Libraries

@kpgalligan
Copy link
Collaborator

My annual reminder that this is just a linker issue. It is expected. Adding the linker flag isn't a "workaround". It's how linking works.

In reference to the solution from @whataa

target 'iosApp' do
  pod 'sqlite3', '~> 3.42.0' // choose your version
end

I haven't tried this, but you should check if you're actually building your own sqlite binary. The iPhone has a sqlite library that you can link to. Building your own will "work", but you'll have a fair bit of binary in your app that you don't need.

Anyway, wherever you see:

Undefined symbols for architecture x86_64: "_sqlite3_bind_blob", referenced from: _SQLiter_SQLiteStatement_nativeBindBlob in result.o "_sqlite3_bind_double", referenced from: _SQLiter_SQLiteStatement_nativeBindDouble in result.o "_sqlite3_bind_int64", referenced from: 
etc...

It's the linker saying it can't find sqlite3. That is always the issue, and the most straightforward answer is always to tell the linker to use the system sqlite3 library by adding -lsqlite3 to the linker flags. The difficult part is finding who is running the linker and where the flag needs to be added. If the Kotlin compiler is failing, then you need to add that to Kotlin config. If Xcode and the iOS build is failing, then it needs to be added in Xcode, for whatever target is failing. Generally that's the app target, and the field is "Other Linker Flags" in build settings.

@Erlan14
Copy link

Erlan14 commented May 18, 2024

XCode > Build Phases > Link Binary With Libraries > and adding the libsqlite3.tbd

@kpgalligan
Copy link
Collaborator

kpgalligan commented May 19, 2024

(Taps the sign...)

#1442 (comment)

XCode > Build Settings > "Other Linker Flags"

Add -lsqlite3.

That is the answer. If you're using the sqlite shipped with all Apple platforms, you need to link to it. Period.

@AungThiha
Copy link

I got it solved by turning static linking off in the shared module.

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = false
        }
    }

I found this from https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-ktor-sqldelight.html#create-the-ios-application

It says and I quote

The Kotlin Multiplatform wizard generates projects set up for static linking of iOS frameworks. To use the SQLDelight library, allow the iOS framework to link dynamically.
To do that, open the shared/build.gradle.kts file and change the isStatic property of the iosTarget.binaries.framework block to false:

@kpgalligan
Copy link
Collaborator

kpgalligan commented Sep 13, 2024

The Kotlin Multiplatform wizard generates projects set up for static linking of iOS frameworks. To use the SQLDelight library, allow the iOS framework to link dynamically.

That's not a good solution from the "official" docs. There are legitimate reasons to not want a dynamic framework.

Again, it is always -lsqlite3. Making the framework "dynamic" embeds that linker flag in the framework package. As an alternative, add -lsqlite3 in Xcode config.

#1442 (comment)

(Taps the sign...)

https://github.com/cashapp/sqldelight/issues/1442#issuecomment-1938897368

XCode > Build Settings > "Other Linker Flags"

Add -lsqlite3.

That is the answer. If you're using the sqlite shipped with all Apple platforms, you need to link to it. Period.

I generally default to static frameworks. Many apps do as well. I'll ping JetBrains about their docs.

Update: Cool, you can actually fork the docs and submit a PR. Hmm...

@kpgalligan
Copy link
Collaborator

@dandehavilland
Copy link

I had a similar issue. Multimodule KMP project, some nested modules, one of which uses sqldelight and has the config in it's gradle file.

I was already applying linkSqlite in the module's gradle :

// data/database/build.gradle.kts

sqldelight {
    linkSqlite = true

    // other config...
}

But this didn't work when building for release (via Xcode -> Product -> Archive).

I applied the same linkSqlite separately in the 'shared' module and it now works:

// shared/build.gradle.kts

sqldelight {
    linkSqlite = true
}

@abbashussain5596
Copy link

linkSqlite = true and Adding -lsqlite3.
Apparently with linkSqlite = true the app was using SEE to encrypt the DB but since iOS 15.2 SEE was removed it just stopped working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests