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

MacCatalyst support #471

Closed ericsink closed 2 years ago

ericsink commented 2 years ago

the app works on iOS but crashes on maccatalyst

Originally posted by @VladislavAntonyuk in https://github.com/ericsink/SQLitePCL.raw/issues/468#issuecomment-1032136588

ericsink commented 2 years ago

Not sure yet how to deal with the native SQLite libraries. Do we need a special build, or does the iOS build or the macOS build work?

edoust commented 2 years ago

Are there any news on this, or is there any workaround? I can't get EntityFramework to run on net6.0-maccatalyst, it does run on net6.0-macos (xamarin20)

ericsink commented 2 years ago

No progress on this yet. I need to figure out how to compile the C code for maccatalyst.

For example, the command line for iphone starts out like this:

xcrun --sdk iphoneos clang -O -miphoneos-version-min=6.0 -arch arm64 

And for macos:

xcrun --sdk macosx clang -dynamiclib -O -arch x86_64 

I assume it's similar to these, but I haven't spent any time yet looking for the answer.

edoust commented 2 years ago

Is there a documentation on how you did it for ios (end to end)? If not can you tell me on which code/ repo exactly you ran the above mentioned command?

Would like to have a quick look myself, since I need SQLite in maccatalyst

ericsink commented 2 years ago

There are no docs, but my build scripts for the native SQLite libraries are over in the ericsink/cb repo.

VladislavAntonyuk commented 2 years ago

it seems to be working fine now: image you can try KanbanBoard and Sqlite samples from https://github.com/VladislavAntonyuk/MauiSamples

Important note: Run the app from Visual Studio. for some reason CLI doesn't work

ericsink commented 2 years ago

@VladislavAntonyuk I haven't looked closely at your samples yet, but just to be clear for anybody else seeing this -- there is currently nothing in SQLitePCLRaw and nothing in the e_sqlite3 build scripts that is specifically for maccatalyst support. If anything works with net6.0-maccatalyst, it is an accident, and I don't know why it works. I recently did a bunch of stuff to get the other net6.0-workloads going in the 2.1-prerelease versions, but nothing for maccatalyst.

I do plan to give this issue some real attention as soon as I can.

VladislavAntonyuk commented 2 years ago

@ericsink seems like Apple did a great job to make iOS code work on macOS with maccatalyst, But definitely waiting for your final release with official maccatalyst support. Thank you!

ericsink commented 2 years ago

seems like Apple did a great job to make iOS code work on macOS with maccatalyst

Maybe so, but I thought I saw somewhere that things should be specifically compiled for maccatalyst. I need to confirm whether that's true. If something seems to work when the docs and specs say it should not, then I wonder why.

And if something works when run from Visual Studio but not from the CLI, then it doesn't work.

:-)

VladislavAntonyuk commented 2 years ago

I didn't investigate it, but probably VS restores packages differently and packs SQLite iOS lib in MacCatalyst. it's the only 1 idea that comes to my mind so far.

edoust commented 2 years ago

@VladislavAntonyuk For me building in VS does not work at all, what version of VS are you using? Are you on an x86 or ARM machine?

VladislavAntonyuk commented 2 years ago

VS for mac 2022. Intel

edoust commented 2 years ago

I always get the error clang++ exited with code 1 in Xamarin.Shared.Sdk.targets, that error is reproducible on two machines that are freshly installed, one with an M1 and one with an Intel processor

Both my machines have VS2022 (latest), Xamarin.Mac (latest) and the latest maui-maccatalyst workload installed

Do you have any special configuration on your system that might be related to this?

VladislavAntonyuk commented 2 years ago

Check XCode version. Check MAUI version. Try install it again sudo dotnet workload install maui. Clean bin/obj First run the build with dotnet cli It should build the app and restore packages Then open VS, select your mac to run the app and click Restore nuget packages on solution Run build from VS. the app may ask for the access to the storage

edoust commented 2 years ago

@VladislavAntonyuk Can you please share your diagnostic build log (especially the xcrun xlang command from the LinkNativeCode target)? I found that in VS build this call fails, so I am interested to know against what sqlite lib you are linking

This is the error message I get: ld: in [...]/obj/Debug/net6.0-maccatalyst/maccatalyst-x64/linker-cache/e_sqlite3.a(sqlite3.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, file '[...]/obj/Debug/net6.0-maccatalyst/maccatalyst-x64/linker-cache/e_sqlite3.a' for architecture x86_64

For RID maccatalyst-arm64 it says the lib was built for iOS not iOS Simulator

@ericsink Thanks for hinting at the cb repo, I could slightly modify your script to build a MacCatalyst compatible version of e_sqlite.a. Currently I can manually copy that file to the linker-cache folder, but I need this to work for CLI (agent) builds as well

Which repo is the base for the NuGet that will contain the maccatalyst support once you publish it? I would like to fork it and create a private NuGet for my CLI (agent) build, since I need EF Core to work on maccatalyst as soon as possible

VladislavAntonyuk commented 2 years ago

BuildLogs.txt

edoust commented 2 years ago

Thanks you, but this log does not contain the clang commands since it was not a full rebuild, so those targets were skipped. Can you please do a full rebuild after having deleted bin and obj folders and only building the target framework maccatalyst?

Also, please share the e_sqlite.a file that is located in obj/Debug/net6.0-maccatalyst/maccatalyst-x64/linker-cache. I would like to check whether you get a library built for maccatalyst already, and if so where that file originally came from

VladislavAntonyuk commented 2 years ago
  1. Delete obj/bin
  2. Run VS and restore packages and build app. Output: BuildLogs.txt
  3. Run dotnet build -t:Run -f net6.0-ios
  4. Run dotnet build -t:Run -f net6.0-maccatalyst output: BuildLogs.txt
  5. Back to VS and run the app.

So from what I see it is important the iOS libs appear in maccatalyst folder, otherwise the app crashes and can't find e_sqlite3

edoust commented 2 years ago

Thanks for sharing the log files. From my understanding in order to be able to use the (iOS-)OS provided SQLite implementation, it would require some reference to it, for example by importing the SQLite header file into a referenced (native) library and actually using its methods. I would assume that SQLitePCLRaw.provider.dynamic_cdecl is a passthrough that relays all calls to e_sqlite3 to the OS-provided version of SQLite (??)

But then I still don't get how this would work with MacCatalyst, since as far as I know MacCatalyst is not just emulating an iOS environment (like x86 env may be emulated on ARM) but it requires a dedicated build for maccatalyst

On my end I got the app working using the CLI by doing the following steps:

  1. Create a maccatalyst build of SQLite using the scripts provided by @ericsink
  2. Referencing the generated libe_sqlite3.dylib with a <NativeReference Include="/.../libe_sqlite3.dylib" Kind="Dynamic" />
  3. Build using CLI dotnet build -t:restore,build KanbanBoard.csproj -f net6.0-maccatalyst

The resulting .app packages work for both the maccatalyst-x64 and maccatalyst-arm64 RIDs, also both contain the libe_sqlite.dylib file (~2MB) inside the package

VladislavAntonyuk commented 2 years ago

as @ericsink mentioned this lib so far works only with net6.0-ios. https://github.com/ericsink/SQLitePCL.raw/blob/9d5a8b6651f5feb31605c7e978aa0f42ad21f6a8/src/SQLitePCLRaw.bundle_e_sqlite3/SQLitePCLRaw.bundle_e_sqlite3.csproj#L4

there is no net6.0-maccatalyst and net6.0-mac target frameworks

edoust commented 2 years ago

For Catalyst it should do a fallback to netstandard2.0. I was just wondering about your logs not showing a native compilation/linking process, so I just don't see how you would get a runnable (deployable) macOS .app package out of it

For me it is working now using a privately published NuGet so I will use that approach going forward

edoust commented 2 years ago

@ericsink

Could you already have a look into rebuilding the NuGet packages? Do you think integrating maccatalyst requires code changes, or should this be done by integrating the dylib files into the lib project and then compiling the bundle project with maccatalyst support?

ericsink commented 2 years ago

@edoust I think what you said is sufficient. I've made those changes and pushed them up. However, the CI builds are currently failing for other reasons. It looks like something in the net6.0-ios SDK broke with this week's preview release. I am investigating.

ericsink commented 2 years ago

Looks like the problem is xamarin/xamarin-macios/issues/14434

ericsink commented 2 years ago

Version 2.1.0-pre20220318192836 has been pushed up to nuget. It contains progress on maccatalyst support.

I tried a very basic test and it seems to work.

One caveat: I placed the native binaries under net6.0-maccatalyst15.2, so it is necessary to target at least that version in order to get the dylib into the build. If I just set TargetFramework to net6.0-maccatalyst (without specifying the version), or if I specify a version below 15.2, the resulting app crashes because it cannot find the dylib. I suspect I don't need to specify a minimum version that high, so another fix is probably needed here.

VladislavAntonyuk commented 2 years ago

it works fine. I set TargetFramework to net6.0-maccatalyst and min version to 15.2

edoust commented 2 years ago

For me it does not work automatically, I need to add a NativeReference explicitly, or else the libe_sqlite.dylib is not put in the app package (I can only use test using the CLI, since VS2022 for mac preview 7 does not support .NET 6 Xamarin projects at the moment)

VladislavAntonyuk commented 2 years ago

@edoust could you try this sample https://github.com/VladislavAntonyuk/MauiSamples/blob/main/KanbanBoard/KanbanBoard.csproj#L36?

edoust commented 2 years ago

Your project is working for net6.0-maccatalyst15.2, without the libe_sqlite.dylib being present in the app package. I narrowed it down to this reference being present, the other ones are not required. <PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220318192836" />

I will re-test my project that with the bundle green reference as soon as I can. Since I installed VS for Mac 2022 preview 7, I can't run .NET6 Xamarin projects anymore, so I am currently blocked (others are too), does VS preview 7 work for you?

VladislavAntonyuk commented 2 years ago

Thank you, I will remove unused packages. VS4Mac doesn't work with MAUI. At least with this release

edoust commented 2 years ago

@ericsink Do you have any idea why bundle green would work whereas bundle e_sqlite would not?

@VladislavAntonyuk do you know why VS4mac does not work anymore maui? I could not find any hint in the docs/blogs/ etc

VladislavAntonyuk commented 2 years ago

They removed this feature from this preview. Probably because of a lot of breaking changes with the latest MAUI. But I know it works in private preview. So probably with the next release they should enable MAUI support again. IntelliSense still works in VS. Alternatively you can use Rider. Probably you can attach to the process, but I didn't try

ericsink commented 2 years ago

@edoust bundle_green is identical to bundle_e_sqlite3 except that on iOS it uses the system-provided SQLite library instead of e_sqlite3. Now that we have maccatalyst support, I made it work the same way for bundle_green.

bstrother1 commented 2 years ago

So is Sqlite working with MacCatalyst now? If so what configurations are required? I'm not seeing any new releases/prereleases since this ticket was created and its still open. Thanks!

ericsink commented 2 years ago

I think the latest pre-release works with MacCatalyst. Let me know if you have trouble with it.

I plan to make a non-pre release very soon.

edoust commented 2 years ago

For me it does not work, I don't know why, none of the preview bundles do. As a workaround I created a custom NuGet file that contains an explicit NativeReference, and I reference that in addition to the official preview packages

I am using the binaries that you checked into the cb repo in my custom NuGet

ericsink commented 2 years ago

OK I need to check this again. I'll see if I can create a working sample.

ericsink commented 2 years ago

Confirmed: I can repro the broken behavior you described. I am working on a fix...

ericsink commented 2 years ago

Prerelease 2.1.0-pre20220427180151 is now on nuget, and contains a fix that works for me.

VladislavAntonyuk commented 2 years ago

Why does it require 15.2 as a minimum version?

ericsink commented 2 years ago

I don't remember why I did that. What should it be?

VladislavAntonyuk commented 2 years ago

I think it should be the same as for .NET MAUI. 14.2 for iOS and 14 for MacCatalyst

ericsink commented 2 years ago

@VladislavAntonyuk Can you link to the source of those version numbers? (Edit: I mean, where are those documented or specified?)

I remember why I chose 15.2 -- when I build a project specifying just net6.0-maccatalyst as the TFM, under the hood, the SDK seems to interpret that as net6.0-maccatalyst15.2. I know I've seen something that specifies the behavior of a net6.0-whatever TFM which doesn't specify a version, but I can't remember where.

VladislavAntonyuk commented 2 years ago

https://github.com/dotnet/maui/blob/272abd1e1d3bb6c09211f5dec575edf1cb23d6a6/src/Templates/src/templates/maui-mobile/MauiApp.1.csproj#L25

coolbluewater commented 2 years ago

@ericsink, when do you think a nuget that supports Mac Catalyst (prerelease or otherwise) will be available? Many thanks for this library!

ericsink commented 2 years ago

@coolbluewater Have you tried Prerelease 2.1.0-pre20220427180151 mentioned above? I think it works with maccatalyst, except of course with the caveat about the minimum supported platform versions as mentioned by @VladislavAntonyuk subsequently.

With .NET MAUI in RC2 now, I need to get the release done soon -- I've just been waiting for any last minute fixes to a couple of other issues.

coolbluewater commented 2 years ago

@ericsink I was already on that version. I changed the <SupportedOSPlatformVersion> on the two projects that are using SQLitePCLRaw (but not on the other projects - is that needed?). Unfortunately, I still get this exception:

System.DllNotFoundException: sqlite3
   at SQLitePCL.SQLite3Provider_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number()
   at SQLitePCL.raw.SetProvider(ISQLite3Provider imp)
   at SQLitePCL.Batteries_V2.Init()

EDIT: I am using Visual Studio for Mac 2022 RC1, with the latest MAUI installation.

ericsink commented 2 years ago

@coolbluewater You've got something else going wrong. What package references do you have?

coolbluewater commented 2 years ago

@ericsink: In a library csproj:

    <PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220427180151" />

And also in the executable's csproj:

    <PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220427180151" />
ericsink commented 2 years ago

The attached sample works for me using either bundle_green and bundle_e_sqlite3. Does your project configuration differ in some way?

mc.tar.gz