ericsink / SQLitePCL.raw

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

DllNotFoundException with classic Xamarin.Mac and arm64 ? #497

Open ericsink opened 2 years ago

ericsink commented 2 years ago

I get the (presumably) same crash in a "classic" Xamarin.Mac app (no .NET6) - same stack trace.

System.DllNotFoundException has been thrown
e_sqlite3 assembly:<unknown assembly> type:<unknown type> member:(null)

I've reported this before here with a workaround that seems to work, but it didn't get any traction.

Originally posted by @tipa in https://github.com/ericsink/SQLitePCL.raw/issues/489#issuecomment-1161349488

richardschoen commented 2 years ago

Just got the same error on a .Net 6.0 simple console app under MacOS 12.4 on M1 hardware.

ericsink commented 2 years ago

@richardschoen I just wrote a simple console app using SQLitePCLRaw 2.1.0 with .NET 6.0 on M1 hardware and it worked fine.

richardschoen commented 2 years ago

@ericsink Are you using VS 2022 or something else like VS Code ? Would you mind posting the project somewhere possibly ? I was also using VS 2022 for Mac

ericsink commented 2 years ago

Normally I prefer that the user with the problem be the one to post repro projects. :-)

But anyway, my quick console app test with was done from the command line, not using any IDE.

If you're on VS for Mac, you're probably seeing #489, not this one. I'm going to rename that one to make it easier to find. It's a known problem that something is going wrong with VS for Mac, and I don't know yet if it's purely an IDE bug or if SQLitePCLRaw is doing something odd that only shows up when VS for Mac is in play.

Either way, your problem is unrelated to this issue here, which is specifically about classic Xamarin.Mac.

richardschoen commented 2 years ago

@ericsink Pretty sure it's VS. Thanks. I'll try from the command line and VS Code and see what I get.

ecsplendid commented 2 years ago

I am using Unity on Macbook Pro M1 and see this error, have no idea what to do

image

DllNotFoundException: e_sqlite3 assembly:<unknown assembly> type:<unknown type> member:(null)
SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number () (at <7158634a0cea490799582053c6fc6ea6>:0)
SQLitePCL.raw.SetProvider (SQLitePCL.ISQLite3Provider imp) (at <00c3759168224530a91b0fc2aa365b59>:0)
DataService..ctor (System.String DatabaseName) (at Assets/Scripts/DataHandler.cs:34)
Database..ctor () (at Assets/Scripts/Database.cs:7)
Logger..ctor (System.String tag_) (at Assets/Scripts/Logger.cs:10)
AudioProcessor.Awake () (at Assets/Scripts/AudioProcessor.cs:61)
ericsink commented 2 years ago

@ecsplendid If you are using Unity, then your issue is completely separate from this one.

tipa commented 2 years ago

@ericsink is there anything I can do to help with this problem? Were you able to reproduce the crash?

ericsink commented 2 years ago

@tipa Looking back through the red herrings of this issue, I'm guessing you're talking about the original problem, which was inability to find the native library under:

a "classic" Xamarin.Mac app (no .NET6)

Can you post a minimal repro project?

tipa commented 2 years ago

Sure, I can reproduce the problem with this project on a M1 Mac mini: SqliteTest.zip

After creating an Exception breakpoint for System.Exception, the debugger should stop at new SQLiteConnection: Screenshot 2022-09-07 at 08 17 44

ericsink commented 2 years ago

I can more or less reproduce the problem with your posted sample. VS 2022 isn't behaving quite right for me, but it will build, and the resulting build output does not contain the libe_sqlite3.dylib file, which is consistent with the error you are seeing. Also, if I run the resulting executable manually from the command line, I get the same exception.

Of course, the main question here is why that file isn't getting included in the build. I don't have an answer for that yet. It's in sqlitepclraw.lib.e_sqlite3 where I would expect it to be.

Maybe xamarin.mac never implemented support for native files stored in the runtimes folder. Or maybe it was implemented but then it got broken during the big net6.0 transition.

tipa commented 2 years ago

The project above is a legacy Xamarin.Mac project, so not sure if it has something to do with .NET6. I made another few observations: The project as I posted it currently compiles and runs in x86_64 config (even on a M1), because ARM64 support is an experimental feature in legacy Xamari.Mac. When adding a reference to SQLitePCLRaw.e_sqlite3.osx, the project starts to work. However, when adding <XamMacArch>x86_64,ARM64</XamMacArch>, the app builds and runs in ARM64 on a M1 and the crash above happens again

ericsink commented 2 years ago

A lot of legacy Xamarin.Mac seems like black magic to me because I haven't really used it. For example, I don't know what the XamMacArch msbuild property is.

It's kind of interesting that things worked when you added SQLitePCLRaw.e_sqlite3.osx. That nuget package is ancient. It's adding a very old version of SQLite. However, that package has one very big difference: It contains a .targets file that adds a NativeReference for the dylib. The current setup doesn't have that, because net6.0 (I think) doesn't need it.

Perhaps I could add a similar bit of msbuild code to the current packages. The trick will be to do so without breaking any of the net6.0 stuff.

ericsink commented 2 years ago

I've got a general idea of what's wrong here, but I'm not sure what the right "fix" is.

I could just do what the old package was doing, but I think that will likely make things work on Arm64 machines and break on Intel machines.

For legacy Xamarin, it's not clear exactly how the msbuild properties involved in the target CPU are supposed to work.

Since this target is going away anyway, I might try to provide something less like a fix and more like a workaround.

tipa commented 2 years ago

Not sure if that information helps, but I ended up adding neither the sqlite-net-pcl nor any SQLitePCL.raw NuGet package to my project but instead just copied this source code file of sqlite-net into my app and things started to magically work, for both x64 and arm64

ericsink commented 2 years ago

Yes, that would work if you want to just use the SQLite lib provided by macOS. There's a configuration using the nuget packages that can accomplish the same thing.

ericsink commented 2 years ago

Possible dupe of #358