ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
512 stars 106 forks source link

.NET 8 on iOS device's error "Unable to load shared library 'e_sqlite3' or one of its dependencies." #593

Closed Insofan closed 3 months ago

Insofan commented 3 months ago

What version of SQLitePCLRaw are you using?

<PackageReference Include="SQLitePCLRaw.core" Version="2.1.8" />

If you are using one of the SQLitePCLRaw bundle packages, which one?

<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.8" />

What platform are you running on? What operating system? Which version? What CPU?

iPhone 12, iOS 15.4.1

What target framework are you building for?

I'm making a game by Godot engine, it depend on .NET 8. I export my game to a Xcode project, build it on iPhone device.

Are you on .NET Framework or the newer stuff (.NET Core, .NET 5+, etc)?

.NET 8

Sometimes other packages using SQLitePCLRaw cause problems when they are mixed together. What other packages are you including in your project?

It depend on sqlite-net, code to call sqlite-net.

            var dbPath = Path.Join(_path, "data.db");
        if (!File.Exists(dbPath))
        {
            File.Create(dbPath);
        }

        SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());
        _conn = new SQLiteConnection(dbPath);

This is my csproj. I tried a lot of combinations, the Xcode error msg seems it cant find sqlite3 on iPhone.

net8.0 net8.0 net8.0 true enable
    <PackageReference Include="SQLitePCLRaw.core" Version="2.1.8" /> 
    <PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.8" />
    <!-- <PackageReference Include="SQLitePCLRaw.bundle_sqlite3" Version="2.1.8" /> -->
    <!-- <PackageReference Include="sqlitepclraw.bundle_e_sqlite3" Version="2.0.5-pre20210119130047" /> -->

</ItemGroup>

What is the exact error message you are seeing when the problem happens?

2024-03-30 04:13:08.638071+0800 Cardlization[3458:231039] USER ERROR: System.DllNotFoundException: Unable to load shared library 'e_sqlite3' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(e_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/e_sqlite3.dylib' (no such file), 'e_sqlite3.dylib' (no such file), '/usr/local/lib/e_sqlite3.dylib' (no such file), '/usr/lib/e_sqlite3.dylib' (no such file), '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3.dylib' (no such file) dlopen(libe_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/libe_sqlite3.dylib' (no such file), 'libe_sqlite3.dylib' (no such file), '/usr/local/lib/libe_sqlite3.dylib' (no such file), '/usr/lib/libe_sqlite3.dylib' (no such file), '/usr/lib/system/introspection/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3.dylib' (no such file) dlopen(e_sqlite3, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/e_sqlite3' (no such file), 'e_sqlite3' (no such file), '/usr/local/lib/e_sqlite3' (no such file), '/usr/lib/e_sqlite3' (no such file), '/usr/lib/system/introspection/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3' (no such file) dlopen(libe_sqlite3, 0x0001): tried: '/usr/lib/system/introspection/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/libe_sqlite3' (no such file), 'libe_sqlite3' (no such file), '/usr/local/lib/libe_sqlite3' (no such file), '/usr/lib/libe_sqlite3' (no such file), '/usr/lib/system/introspection/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3' (no such file)

at System.Runtime.InteropServices.NativeLibrary.LoadLibErrorTracker.Throw(String) + 0x58 at Internal.Runtime.CompilerHelpers.InteropHelpers.FixupModuleCell(InteropHelpers.ModuleFixupCell) + 0x164 at Internal.Runtime.CompilerHelpers.InteropHelpers.ResolvePInvokeSlow(InteropHelpers.MethodFixupCell) + 0x44 at Internal.Runtime.CompilerHelpers.InteropHelpers.ResolvePInvoke(InteropHelpers.MethodFixupCell*) + 0x30 at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_libversion_number() + 0x34 at SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number() + 0x10 at SQLitePCL.raw.SetProvider(ISQLite3Provider) + 0x70 at Manager.DBManager._EnterTree() + 0xf0 at Godot.Node.InvokeGodotClassMethod(??? method, NativeVariantPtrArgs args, godot_variant& ret) + 0x15c at Manager.DBManager.InvokeGodotClassMethod(??? method, NativeVariantPtrArgs args, godot_variant& ret) + 0x308 at Cardlization!+0x895b1c 2024-03-30 04:13:08.639422+0800 Cardlization[3458:231039] at: void Godot.NativeInterop.ExceptionUtils.LogException(System.Exception) (:0) USER ERROR: System.DllNotFoundException: Unable to load shared library 'e_sqlite3' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(e_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/e_sqlite3.dylib' (no such file), 'e_sqlite3.dylib' (no such file), '/usr/local/lib/e_sqlite3.dylib' (no such file), '/usr/lib/e_sqlite3.dylib' (no such file), '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3.dylib' (no such file) dlopen(libe_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/libe_sqlite3.dylib' (no such file), 'libe_sqlite3.dylib' (no such file), '/usr/local/lib/libe_sqlite3.dylib' (no such file), '/usr/lib/libe_sqlite3.dylib' (no such file), '/usr/lib/system/introspection/libe_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3.dylib' (no such file) dlopen(e_sqlite3, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/e_sqlite3' (no such file), 'e_sqlite3' (no such file), '/usr/local/lib/e_sqlite3' (no such file), '/usr/lib/e_sqlite3' (no such file), '/usr/lib/system/introspection/e_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/e_sqlite3' (no such file) dlopen(libe_sqlite3, 0x0001): tried: '/usr/lib/system/introspection/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/Frameworks/libe_sqlite3' (no such file), 'libe_sqlite3' (no such file), '/usr/local/lib/libe_sqlite3' (no such file), '/usr/lib/libe_sqlite3' (no such file), '/usr/lib/system/introspection/libe_sqlite3' (no such file), '/private/var/containers/Bundle/Application/2CEC6C88-303A-4DB5-B9CC-0BF1CA9DCEE7/Cardlization.app/libe_sqlite3' (no such file)

at System.Runtime.InteropServices.NativeLibrary.LoadLibErrorTracker.Throw(String) + 0x58 at Internal.Runtime.CompilerHelpers.InteropHelpers.FixupModuleCell(InteropHelpers.ModuleFixupCell) + 0x164 at Internal.Runtime.CompilerHelpers.InteropHelpers.ResolvePInvokeSlow(InteropHelpers.MethodFixupCell) + 0x44 at Internal.Runtime.CompilerHelpers.InteropHelpers.ResolvePInvoke(InteropHelpers.MethodFixupCell*) + 0x30 at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_libversion_number() + 0x34 at SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number() + 0x10 at SQLitePCL.raw.SetProvider(ISQLite3Provider) + 0x70 at Manager.DBManager._EnterTree() + 0xf0 at Godot.Node.InvokeGodotClassMethod(??? method, NativeVariantPtrArgs args, godot_variant& ret) + 0x15c at Manager.DBManager.InvokeGodotClassMethod(??? method, NativeVariantPtrArgs args, godot_variant& ret) + 0x308 at Cardlization!+0x895b1c at: void Godot.NativeInterop.ExceptionUtils.LogException(System.Exception) (:0)

ericsink commented 3 months ago

You're calling

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());

but for iOS, that initialization code isn't quite right, because the native library is statically linked.

Since you're using one of the bundle packages, try replacing that line with

SQLitePCL.Batteries.Init()

which will do the right initialization for the platform.

Insofan commented 3 months ago

@ericsink I have changed the code

        SQLitePCL.Batteries.Init();
        _conn = new SQLiteConnection(dbPath);

It still output error msg in Xcode.

2024-03-30 05:25:46.424237+0800 Cardlization[3809:252021] USER ERROR: System.DllNotFoundException: Unable to load shared library 'e_sqlite3' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(e_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file),

ericsink commented 3 months ago

That shouldn't be happening. Do you have some other package involved which uses SQLitePCLRaw ?

Insofan commented 3 months ago

That shouldn't be happening. Do you have some other package involved which uses SQLitePCLRaw ?

No, the csproj up comment is all, should I add or delete some dependcies? Dose it cause by sqlite-net? Or do u know any other sqlite orm package on nuget worked on iOS device. PS: Thx for your repo and replies, It works on Windows and MacOS (x64) platform's Godot's editor.

Insofan commented 3 months ago

@ericsink This error seems not cause by Godot engine. But I don't know about xamarin, is there any other way to reproduce error on ios device. Or should I provide a godot demo to reproduce it.

ericsink commented 3 months ago

I don't know what dependencies you could add or delete to make a difference. I don't know if sqlite-net is causing the problem, but that seems unlikely.

Something in your build setup is referencing e_sqlite3 as a shared library on iOS, but I don't know what it would be. SQLitePCLRaw doesn't do that.

You could remove things until the problem stops. Or you could start with an minimal empty project, add a simple SQLite test, and then add other things back until the problem appears.

Be sure to try a completely clean build output directory, to make sure nothing is getting left over from a previous build.

Insofan commented 3 months ago

You could remove things until the problem stops. Or you could start with an minimal empty project, add a simple SQLite test, and then add other things back until the problem appears.

I have try it. Make a demo, only contain SQLitePCL without sqlite-net or others. Call it

        _conn = GetNode<Button>("Conn");
        _conn.Pressed += (() =>
        {
            Console.WriteLine("Hello 1");
            SQLitePCL.Batteries.Init();
            Console.WriteLine("Hello 2");
        });

Still same error in Xcode, Here's Demo repo , only depend on SQLitePCLRaw.core and SQLitePCLRaw.bundle_green. And add libsqlite3.tbd in Xcode link binary. Error messages:

2024-03-30 07:16:05.616527+0800 Godot[4143:277604] USER ERROR: System.DllNotFoundException: Unable to load shared library 'e_sqlite3' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(e_sqlite3.dylib, 0x0001): tried: '/usr/lib/system/introspection/e_sqlite3.dylib' (no such file), '/private/var/containers/Bundle/Application/1EBF3C8E-B4E2-40F2-BAB4-89D4F3A6CA30/Godot.app/e_sqlite3.dylib' (no such file), ...................

Should I use the no-xamarin branch code?

ericsink commented 3 months ago

Your demo repo still has Godot in it. Maybe there is some sort of incompatibility with Godot?

Wait, actually that does look like it's part of the problem. From the perspective of .NET, the TargetFramework is net8.0, which means you're not actually building for iOS, at least as far as the .NET build system knows.

If your csproj looks like what Godot needs it to be, then yeah, SQLitePCLRaw currently has a compatibility problem with Godot.

Insofan commented 3 months ago

@ericsink I found this Unity solution. It WORKS on Godot engine export ios ipa, I haven't test it on android, But I think it will works. THX for ur repo and replies. Sub is my csproj, I think this is the general solution on iOS without Xamarin. Do not dep on SQLitePCLRaw.bundle_green.Hope it will help someone. I gonna close this issue. Thx again.

<Project Sdk="Godot.NET.Sdk/4.2.1">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net8.0</TargetFramework>
        <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
        <EnableDynamicLoading>true</EnableDynamicLoading>
        <Nullable>enable</Nullable>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
        <PackageReference Include="sqlite-net-pcl" Version="1.9.172"/>

        <PackageReference Include="SQLitePCLRaw.core" Version="2.1.8" /> 
        <PackageReference Include="SQLitePCLRaw.bundle_sqlite3" Version="2.1.8" />

    </ItemGroup>
</Project