← Blog

Whid — The Origin

Chapter 3: Kotlin/Native Shared Library and SQLDelight on Windows

15 April 2022

In general, I think of myself as a very patient person. But if Paul could click and type just a tiny bit faster… I just had to express my frustration:

- I’m sorry, but this is sooo slooow…

- Heh, says the snail - giggled Paul, who seemed to be annoyingly confident since joining our “fedex” group.

TLDR; Issues with the setup

Setting up a Kotlin Native project in IntelliJ on Windows

Hubert has already created an IntelliJ project with Kotlin Multiplatform and SQLDelight, generating the binaries for MacOS. This was of course failing on a Windows setup, as the framework could not be generated accordingly:

Cannot create a framework: debugFramework. Binaries of this kind are not available for target native

If you take a closer look at the original code snippet, the name of the host OS was already exported from the System property os.name as the hostOs variable. This could also be used to generate the binaries based on the target system. Here is the updated section of the build.gradle.kts file:

    nativeTarget.apply {
        binaries {
            if (isMingwX64) {
                sharedLib {
                    baseName = "libWitchesHideousIdeaBackend"
                }
            } else if (hostOs == "Mac OS X") {
                framework {
                    baseName = "WitchesHideousIdeaBackend"
                }
            }
        }
    }

This way we could trigger generating the .dll file which would be found in build/bin/native/debugShared and build/bin/native/releaseShared. Unfortunately the gradle build failed with an error message:

lld: error: unable to find library -lsqlite3 clang++: error: linker command failed with exit code 1 (use -v to see invocation)

Setting up SQLite for Clang on Windows

SQLite is available by default on MacOS, but it is not the case on Windows. We downloaded the Precompiled Binaries for Windows from the official SQLite website and added their folder to the environment variable LIBRARY_PATH. This resulted in a different error message when we triggered the gradle build again:

lld: error: lld doesn't support linking directly against C:\path\to\sqlite\sqlite3.dll, use an import library clang++: error: linker command failed with exit code 1 (use -v to see invocation)

To resolve this issue, we had to generate a .lib file from the .dll file. Fortunately a nice person on StackOverflow has already solved this issue and created a git repository with the necessary steps. We just also had to download the Source Code of SQLite to the same folder, and use the Developer Command Prompt for VS 2022 to create the .lib file. For that, we needed a Visual Studio installed, but as in the company we have a C# project running, I already had to install it a few weeks ago. In the command prompt you have to navigate to the folder of the source files and precompiled binaries, and run the following command:

lib /DEF:sqlite3.def /OUT:sqlite3.lib /MACHINE:x64

This time the gradle build ran without errors.

Where is my database file of SQLDelight on Windows?

Hubert’s first setup generated a file for our database, but it became invalid after the database schema has changed during development. This resulted in the following error messages at runtime:

co.touchlab.sqliter.interop.SQLiteExceptionErrorCode: error while compiling: DELETE FROM timeEntries
    at kfun:kotlin.Throwable#(kotlin.String?;kotlin.Throwable?){} (00007ff60d4cad90)
    at kfun:kotlin.Throwable#(kotlin.String?){} (00007ff60d4cb0c0)
    at kfun:kotlin.Exception#(kotlin.String?){} (00007ff60d4c4630)
    at kfun:co.touchlab.sqliter.interop.SQLiteException#(kotlin.String;co.touchlab.sqliter.interop.SqliteDatabaseConfig){} (00007ff60d6136b0)
    at kfun:co.touchlab.sqliter.interop.SQLiteExceptionErrorCode#(kotlin.String;co.touchlab.sqliter.interop.SqliteDatabaseConfig;kotlin.Int){} (00007ff60d613780)
    at kfun:co.touchlab.sqliter.interop.SqliteDatabase#prepareStatement(kotlin.String){}co.touchlab.sqliter.interop.SqliteStatement (00007ff60d616a30)

To get rid of this error, we saw two ways:

You can already find in Hubert’s post how to resolve both on MacOS.

If you would like to delete the database file, by default there are three files generated:

If you are not migrating an existing schema, just working on setting up your tables, you can easily delete these files, they will be regenerated next time when you start your app.