-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Binding project using xcframework can't be used in Xamarin.iOS app #10774
Comments
I've did some more testing and it seems that including the xcframework in the Xamarin.iOS app directly and not in the binding project it seems to works fine (the proper architecture in the xcframework gets picked for both simulator and device builds in the build process and the code called through the API binding works fine). So this seems to be a issue related to the build process "importing" the xcframework from a reference project/dll/assembly, rather than a xcframework support issue as a whole. So if you have access to the xcframework of the library you want to use you can include it in the Xamarin.iOS project directly as a temporary workaround until this issue is fixed. Note: The workaround only works on Visual Studio on Mac (Visual Studio 2019 on Windows still has a few bugs regarding xcframeworks) |
Thanks for the report. I'll have a look shortly...
Please file separate issues for them and specify they are only happening on Windows. Thanks! |
Thanks! I've filed a separate issue for the Windows exclusive issues here: #10784 |
@leonluc-dev just to be clear - the original attached project (in the main description) works without modification, right ?
|
@spouliot The BindingTest.zip in the original post is the one showing the issue (xcframework is in the binding project, main app just has a reference to the binding project) and doesn't build properly. The Bindingtest-fixed.zip in the later comment shows the temporary workaround which does build (xcframework in main app, binding project is just the C# api definition). |
hmm, that's not what I downloaded... |
I'm hitting a localization issue (that I'll need to fix first, since it hides an issue) but I'm fairly sure the problem is (at least in part) because of the lack of
inside your binding project, In short, it's not really possible (at least it's a very bad idea [1]) to embed an .xcframework inside the assemblies. So we keep the native code in a "side car" with a manifest file that describe the arguments to be used. That is not new but, for compatibility, this was not the default for bindings. Now xcframework are new and makes this option even more important [2]. [1] is was already a bad idea for framework and even before, bitcode really made this a bad choice. The "cost" (in time) to extract the native code on each clean (not cached) build can be extremely large for some projects (larger than the rest of the build). [2] it's even worse for .xcframework since assemblies are per-platforms (one for iOS, one for tvOS, one for watchOS, one for macOS...) and this would embed the native code for all platforms into each platform specific assemblies. |
I see. I'm not sure if I understand correctly, but the 'workaround' mentioned earlier (NativeReference to xcframework in app and just the C# binding definition in the binding project, combined with the NoBindingEmbedding option), is the supposed way to go for xcframeworks or even framework based libraries in general? |
Not quite. The native reference should only be needed for the binding project(s) but, without So
and
|
Alright. Thanks for the information! After setting the NoBindingEmbedding in the csproj file it seems to work properly now. The binding project generates a DLL and a .resource folder containing the xcframework and manifest and the app seems to build properly now. In other contexts (direct distribution of the binary files or NuGet for example), would making sure the .resource folder is in the same folder as the referenced dll be enough to make it work? |
Yes, the native bits are meant to be side-by-side (the "side car"). As for nuget it might be tricky since both nuget and xcframework are similar in design/goals but quite different in their implementation (nothing to do with Ideally you would want a single copy of any |
Code shared between msbuild and mtouch/mmp needs to share the localization strings, otherwise the exception being thrown is of no help to solve the issue. THis happened if a wrong path was given for an `.xcframework` and `FileCopier` reported an `MT1022` error. Reference (not a fix for) xamarin#10774
…mmp (#10799) Code shared between msbuild and mtouch/mmp needs to share the localization strings, otherwise the exception being thrown is of no help to solve the issue. THis happened if a wrong path was given for an `.xcframework` and `FileCopier` reported an `MT1022` error. Reference (not a fix for) #10774
After some experimenting it seems that simply referencing the binding project dll and placing the .resources folder in the same folder as the dll works, but only on Mac. On Mac I am still working on getting this side-car setup to work in NuGet packages. Creating a NuGet package using the project pack command without a nuspec file only adds the dll to the package, so a custom nuget package needs to be made to add the .resources folder as well. I've tried to add the .resources file to the |
@leonluc-dev thanks for your investigations. I'm not an expert on nuget so I'll open a different issue to see how this should be handled. Also please add any Windows-specific information inside #10784. I assumed the "side car" was working on Windows but I'm not fully sure anymore (it seems the cases I thought about actually did not use the feature). I'll update the bindings documentation for "side car" and, once published, close this issue. Thanks! |
Thanks, this was really helpful, but in my own case, something was still missing and, even though the binding project built without errors, I was getting errors when trying to use the binding project (added inside references) in an app. After some investigation, I've found out that when the XCFramework was added to the project, VS added it to .csproj file like this:
I then realised this shouldn't be like this, because a XCFramework is not a static library (.a file). I changed it to:
And now it's working correctly without errors 🔥 I'll write a medium article about what I did and I'll add the link here as soon as I have it ready :) |
@carlosmacmar : how did you generate your metadata? I tried with sharpie but it says error
Thanks |
namespace UniversalBinding
|
For NuGet packages usually XamarinDownloadBuild is used to download and include the .xcframework inside the consuming project by a |
NoBindingEmbedding = true is required when using an XCFramework, otherwise the comsuming app project will get linker errors on Objective-C classes. The details what NoBindingEmbedding does and why it is needed for XCFrameworks is limited. The source where this setting was found is below: - xamarin/xamarin-macios#10774 (comment)
How do we generate the metadata ( Previously, we used sharpie, but sharpie seems incompatible with XCFrameworks. I'm binding a framework with hundreds of APIs, so manually creating @carlosmacmar - How did you generate it? Thanks. |
@joemather You need point to the Framework inside the XCFramework. |
@4brunu - That works. Thank you! For other devs trying to generate metadata, here's the command that worked for me:
Also, this article explains how to fix "file not found" errors when sharpie fails to resolve |
"NoBindingEmbedding = True" is required when using an XCFramework, otherwise the comsuming app project will get linker errors on all Objective-C classes. xamarin/xamarin-macios#10774 (comment)
have you been able to successfully setup NuGet Package? If so - could you please share some more info? |
@nrudnyk If you don't want to do all this manual configuration you can wait until .NET MAUI (along with .NET for iOS) releases later this year, which will support XCFrameworks in NuGet out of the box. |
Do you have a link to a Documentation about the support of XCFrameworks into .NET MAUI ? |
@leonluc-dev I did exactly as described:
This results in Nuget Package which contains everything, but after adding it into the project, it copy files directly to the project, instead of NativeReference:
what am I missing? |
@nrudnyk In your targets file (which is "run" just before compiling starts, as indicated at the top) you first copy the bindings resources from the NuGet package to You need to make sure the nativereference you add during the build process (using the targets file) refers to the xcframework located in the folder you copied one step earlier. As for why the files are added to the project as None references I'm not sure. I haven't seen that happen before. |
Thanks @leonluc-dev, I've updated .targets to the following:
and that does helped to fix the latter issue. Thanks a lot! With that sorted out, I've faced another issue Another important thing, that adding package is taking very long time, it is adding file by file for each platform and it takes like 10-15 minutes easily... have anyone faced similar issue? what do you thing about this @rolfbjarne ? Screen.Recording.2022-03-08.at.23.19.33.mov |
@4brunu Hello. How can I generate metadata via sharpie simultaneously for both |
You can't do both at once, as far as I know. |
Thanks a lot for this information! |
@leonluc-dev Can you please help me with documentation on how to integrate xcframework with a Xamarin iOS project by creating a binding project. |
FYI: instead of |
@leonluc-dev Can you please help me with documentation on how to integrate xcframework with a Xamarin iOS project by creating a binding project. |
xcframeworks work in Xamarin.iOS projects now, so I don't think there's anything left to do here. Also, in .NET, it's possible to run |
Steps to Reproduce
Expected Behavior
The build process includes the native reference (or derived framework in case of xcframework) used in the referenced binding project.
Actual Behavior
If a xcframework was used as a native reference in the binding project the expected derived framework isn't included in the Xamarin.iOS build process, which causes builds to fail with a MT5211 error.
I've added an example project showcasing the issue below (using the Universal.xcframework that was supplied for xcframework testing).
Environment
Example Project (If Possible)
BindingTest.zip
The text was updated successfully, but these errors were encountered: