SQLCipher in Multiplatform iOS build not encrypted - how to debug?

Hey everyone, I have an app based on Kotlin Multiplatform that uses sqldelight and I’d like to encrypt the SQLite DB. I am on the iOS side right now.

I have integrated SQLCipher by following the Option 1: Source Integration.

I set linkSqlite.set(false) to false in my build.gradle.kts file in the sqldelight settings.

I also included setting the -lsqlite3 flag by putting this code part into the same build.gradle.kts file:

project.extensions.findByType(KotlinMultiplatformExtension::class.java)?.apply {
    targets
        .filterIsInstance<KotlinNativeTarget>()
        .flatMap { it.binaries }
        .forEach { compilationUnit ->
            compilationUnit.linkerOpts("-lsqlite3")
        }
}

But the final db in the iOS Simulator is not encrypted.

Of course I also set a key when I create the native driver:

...
encryptionConfig = DatabaseConfiguration.Encryption(key = "testKey")
...

I can also see that xCode does create an sqlite3.o file in it’s build dir.

How can I debug this? Or verify interim results to further narrow down where this goes wrong?

If you are including the amalgamation directly into the build you should not include -lsqlite3 as a linker flag. It will cause the system sqlite3 library to be linked.

Thank you. That makes sense.
I included it after the linker complained about missing sqlite.
What could be wrong if I’m including the amalgamation directly but the linker still complains about sqlite3 being missing.
Is maybe the settings of linkSqlite.set(false) not working?

Hello @dusiema - if the linker is complaining about missing SQLite, I would look at the build log to see if sqlite3.o, which you mentioned is being generated, is actually being used at the link step. It would also be helpful to know what the exact linker errors are.

Hello @sjlombardo,

If I remove the -lsqlite3 then I get the error:

Undefined symbols for architecture arm64:
  "_sqlite3_bind_blob", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_blob_wrapper69 in result.o
  "_sqlite3_bind_double", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_double_wrapper71 in result.o
...
> Task :shared:linkDebugFrameworkIos FAILED
...

I cleaned the build in xCode and started the build again then looked for a sqlite3.o file in ~/Library/Developer/Xcode/DerivedData/<myAppFolder>.
But all I can find is a sqlite3.o-39ESKFLVMZ17D file at

/Users/dusiema/Library/Developer/Xcode/DerivedData/iosApp-aieokchpdrcoyoadihmecpqhvuwm/Index.noindex/DataStore/v5/units/sqlite3.o-39ESKFLVMZ17D

Am I missing something so the sqlite3.o does not get compiled or is the sqlite3.o-39ESKFLVMZ17D file what should get used in the build & link process?

Just to reassure I added the lsqlite3 flag again. Then the build completes and there is a sqlite3.o file at

/Users/dusiema/Library/Developer/Xcode/DerivedData/iosApp-aieokchpdrcoyoadihmecpqhvuwm/Build/Intermediates.noindex/iosApp.build/Debug-iphonesimulator/testApp.build/Objects-normal/arm64/sqlite3.o

I wonder if the combination of sqldelight, SQLiter and SQLCipher in a Kotlin Multiplatform App-Project only works with Cocoapods and not with the source/amalgamation integration?

Almost all the documentation I can find uses Cocoapods and kind of recommends it. In this article by Sam Hill he states:

…This will handle all the CInterop for you and fulfill SQLiter’s requirements…

Whatever those requirements exactly are. I was hoping I could get away with not introducing Cocoapods into my project.

It seems to me the linking of lsqlite3 is necessary for SQLiter to work.

(Sorry for posting 3 times.)

(EDIT: I posted a question at SQLiter discussion board: SQLCipher integration without cocoapods (but with source/amalgamation) · cashapp/sqldelight · Discussion #4638 · GitHub)