I am just trying to get an older multiplatform pro...
# compose-ios
m
I am just trying to get an older multiplatform project working again (Android, iOS, Desktop). The new structure was created by the Jetbrains Multiplatform Wizard and the old code was then moved over to the new structure. On Android and Desktop it works perfectly already but when I build for the iOS simulator (I don’t have a real iOS device) I get lots of error messages like this:
Copy code
ld: Undefined symbols:
  _sqlite3_bind_blob, referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_blob_wrapper69 in composeApp[4](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o)
  _sqlite3_bind_double, referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_double_wrapper71 in composeApp[4](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o)
  _sqlite3_bind_int64, referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_int64_wrapper73 in composeApp[4](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o)
  _sqlite3_bind_null, referenced from:
      _co_touchlab_sqliter_sqlite3_sqlite3_bind_null_wrapper74 in composeApp[4](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o)
...
Does anyone know what might be going wrong here? I am not using any of the touchlab tools directly. These dependencies seem to be pulled in by SQLDelight. I have tried this on an X86 Mac as well as on an ARM Mac in case that should matter.
p
m
I tried adding this to the already existing, generated
forEach
Copy code
listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
        iosTarget.binaries.all {// See: <https://kotlinlang.slack.com/archives/CTJB58X7X/p1706694479715499?thread_ts=1706694023.541669&cid=CTJB58X7X>
            linkerOpts.add("-lsqlite3")
        }
    }
but it does not make any difference. What finally solved this problem for the moment is setting
isStatic = false
and remove that
Copy code
iosTarget.binaries.all {// See: <https://kotlinlang.slack.com/archives/CTJB58X7X/p1706694479715499?thread_ts=1706694023.541669&cid=CTJB58X7X>
            linkerOpts.add("-lsqlite3")
        }
again. I read that using
isStatic = false
is not supposed to be a good idea although, as a non-iOS programmer I have no idea what the consequences may be. So this problem is solved for the moment but just to stumble into the next one. But that’s unrelated to this one has to wait until tomorrow.
👍 1
p
You can find a lot of documentation talking about static vs dynamic compilation. In the java world basically everything is dynamic. You build against a library dependency and ship your library with the links to the dependency but without the dependency itself. In the final build, all libraries links are resolved and one binary is included with all the libraries. In static compilation, you include the third party dependency binary in your library, the code compiled not the links. So if another library do the same, in the final compilation both binaries will be present, and the compiler doesn't have a way to detect that so it ships both binaries. Since it can duplicate binaries it increases size and that is why is discouraged.
s
SQLiter is a bit slow to update, maybe you can try this: https://github.com/ctripcorp/SQLlin/tree/main/sqllin-driver
m
@Pablichjenkov But the default and recommendation is just the opposite of what you say. One should use static linking if possible. But this default just cost me two days because obviously the compose build process fails with it at least for some external libraries, like SQLDelight in my case. After all it is still alpha, so I don’t complain. @SeikoDes Thanks for the hint but exchanging the driver with yours somehow did not work. I’ll just stick with the dynamic linking solution for now.
p
I believe(I might be wrong) the reason why dynamic linking is not defaulted is because some technical limitation. Some one from Jetbrains can correct me. But in general, when you talk to an iOS developer they will say they prefer dynamic compilation/linking over static for sizing reasons.
m
This article describes why static linking may be better. https://www.emergetools.com/blog/posts/static-vs-dynamic-frameworks-ios-discussion-chat-gpt (Forget the ChatGBT stuff) But I’ll use whatever works and static linking does NOT work for me at the moment.
👍 2
p
Thanks for sharing, checking it later
k
I had the same issue with my iOS App.
Copy code
ld: warning: Could not parse or use implicit file '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/SwiftUICore.framework/SwiftUICore.tbd': cannot link directly with 'SwiftUICore' because product being built is not an allowed client of it Undefined symbols for architecture arm64: "_sqlite3_bind_blob", referenced from: _co_touchlab_sqliter_sqlite3_sqlite3_bind_blob_wrapper69 in KrailApp[6](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o) "_sqlite3_bind_double", referenced from: _co_touchlab_sqliter_sqlite3_sqlite3_bind_double_wrapper71 in KrailApp[6](libco.touchlab:sqliter-driver-cinterop-sqlite3-cache.a.o) "_
Copy code
sqlDelight = "2.0.2"
ktor = "3.0.1"
compose-multiplatform = "1.7.0"
Tried adding the linker options
linkerOpts.add("-lsqlite3")
, but that did not fix it and then tried setting
isStatic = false
, which worked. Though am wondering, if there is an update in the compose-ios community on this as
isStatic
should be set to true?
a
Did you try to add
-lsqlite3
to the "Other Linker Flags" in XCode?
🙏 1
k
Thank you! @Andrei Salavei Yea, that worked. I was typing this as you commented 😄 : UPDATE: Was googling and stumbled upon this comment on github: https://github.com/sqldelight/sqldelight/issues/5368#issuecomment-2324975285 https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-ktor-sqldelight.html#add-the-dynamic-linking-flag-for-sqldelight I tried the fix mentioned in docs above and it worked for me, so no longer have to set isStatic as false, which is good. Fix: • In XCode. Go to Build Settings > Other Linker Flags (Other LD_FLAG) • Add
-lsqlite3
string