SQLiter icon indicating copy to clipboard operation
SQLiter copied to clipboard

Undefined symbols for architecture arm64

Open vanniktech opened this issue 3 years ago • 2 comments

I'm currently using sqldelight 2.0.0-alpha03 and when trying to use the native in memory database on iOS in tests (./gradlew iosSimulatorArm64Test)

I get:

w: Mimalloc allocator isn't supported on target ios_simulator_arm64. Used standard mode.
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: warning: object file (/var/folders/mg/nrx5qjvs09v1wfmrfrlpnd800000gn/T/konan_temp4851479586738549723/result.o) was built for newer iOS Simulator version (14.0) than being linked (9.0)
Undefined symbols for architecture arm64:
  "_sqlite3_column_type", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_type_wrapper108 in result.o
  "_sqlite3_finalize", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_finalize_wrapper109 in result.o
  "_sqlite3_column_text", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_text_wrapper103 in result.o
  "_sqlite3_column_name", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_name_wrapper87 in result.o
  "_sqlite3_prepare16_v2", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_prepare16_v2_wrapper61 in result.o
  "_sqlite3_bind_text", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_text_wrapper75 in result.o
  "_sqlite3_clear_bindings", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_clear_bindings_wrapper85 in result.o
  "_sqlite3_bind_null", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_null_wrapper74 in result.o
  "_sqlite3_column_double", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_double_wrapper100 in result.o
  "_sqlite3_close_v2", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_close_v2_wrapper7 in result.o
  "_sqlite3_busy_timeout", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_busy_timeout_wrapper22 in result.o
  "_sqlite3_bind_double", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_double_wrapper71 in result.o
  "_sqlite3_column_blob", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_blob_wrapper99 in result.o
  "_sqlite3_step", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_step_wrapper97 in result.o
  "_sqlite3_column_bytes", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_bytes_wrapper106 in result.o
  "_sqlite3_bind_parameter_index", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_parameter_index_wrapper84 in result.o
  "_sqlite3_db_readonly", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_db_readonly_wrapper177 in result.o
  "_sqlite3_bind_blob", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_blob_wrapper69 in result.o
  "_sqlite3_errmsg", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_errmsg_wrapper53 in result.o
  "_sqlite3_reset", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_reset_wrapper110 in result.o
  "_sqlite3_changes", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_changes_wrapper16 in result.o
  "_sqlite3_db_config", referenced from:
      knifunptr_co_touchlab_sqliter_sqlite314_sqlite3_db_config in result.o
  "_sqlite3_open_v2", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_open_v2_wrapper43 in result.o
  "_sqlite3_column_int64", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_int64_wrapper102 in result.o
  "_sqlite3_bind_int64", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_int64_wrapper73 in result.o
  "_sqlite3_last_insert_rowid", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_last_insert_rowid_wrapper14 in result.o
  "_sqlite3_exec", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_exec_wrapper8 in result.o
  "_sqlite3_column_count", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_column_count_wrapper86 in result.o
  "_sqlite3_close", referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_close_wrapper6 in result.o
ld: symbol(s) not found for architecture arm64

Is it really just adding suppot for arm64 here or is there more crafting involved?

vanniktech avatar Aug 04 '22 18:08 vanniktech

Need to add the sqlite linker arg -lsqlite3. See long thread discussing: https://github.com/cashapp/sqldelight/issues/1442#issuecomment-1048131450

kpgalligan avatar Aug 04 '22 19:08 kpgalligan

I've tried:

kotlin {
  [
    iosX64(),
    iosArm64(),
    iosSimulatorArm64(),
  ].forEach {
    it.binaries.all {
      freeCompilerArgs += "-Xg0" // Required for CrashKiOS.
      if (it instanceof org.jetbrains.kotlin.gradle.plugin.mpp.Framework) {
        it.isStatic = true // Required for CrashKiOS.
        it.linkerOpts.add("-lsqlite3")
        it.embedBitcode("YES".equals(System.getenv("ENABLE_BITCODE")) ? "bitcode" : "marker")
        it.setFreeCompilerArgs(it.getFreeCompilerArgs() + "-Xobjc-generics")
      }
    }
  }
}

Does not seem to do the trick though.

vanniktech avatar Aug 04 '22 19:08 vanniktech

Sorry for delay here. Was this resolved? Will take a look on newer sqldelight releases if not. At the end of the day, it's always some form of -lsqlite3 is missing somewhere, but occasionally it's in an unexpected place.

kpgalligan avatar Dec 07 '22 13:12 kpgalligan

Nope. Still getting that failure.

vanniktech avatar Dec 07 '22 15:12 vanniktech

@vanniktech did you find a fix? I'm facing a similar issue and I've tried all possible linking solutions and am still unable to run ./gradlew iosSimulatorArm64Test

I have a shared module that contains database stuff and shared-ui for presentation logic that exports shared. I can run ./gradlew :shared:iosSimulatorArm64Test and it works, however when trying to run shared-ui tests it fails.

lcszc avatar Jan 08 '23 13:01 lcszc

Nope. I have the exact same issue as you do.

vanniktech avatar Jan 08 '23 15:01 vanniktech

I have the same problem. I also have a separate module for database stuff. I've found that if I add the sqldelight plugin to both modules while keeping the sqldelight configuration block only in the database module, everything compiles and links properly, but I lose the on-the-fly code generation and other niceties sqldelight provides.

humblehacker avatar Mar 16 '23 12:03 humblehacker

So I went spelunking around in the SQLDelight gradle plugin source to see if I could find how adding the plugin to my shared project solved the linking problem. Then I thought I could just pull that out and use it, avoiding the other problems the plugin was causing. Well, I found it and it worked!

If I add this to my shared build.gradle.kts file right below the android block, all methods of building work, and the above workarounds are no longer necessary:

fun Project.linkSqlite() {
    val extension = project.extensions.findByType(org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension::class.java) ?: return
    extension.targets
        .filterIsInstance<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>()
        .flatMap { it.binaries }
        .forEach { compilationUnit ->
            compilationUnit.linkerOpts("-lsqlite3")
        }
}

linkSqlite()

This is a literal cut-and-paste. I'm not a gradle expert and I haven't done anything to clean it up yet. But this is my fourth attempt over many months of trying to get this to work, so I'm happy to finally have a solution.


After some minor clean-up:

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

humblehacker avatar Mar 16 '23 14:03 humblehacker

Closing this. Please re-open and let us know if you're still having issues

samhill303 avatar Apr 17 '23 18:04 samhill303