Skip to content
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

Automatically include .framework or .a files in the NuGet's runtimes/ios/native folder #11667

Closed
Tracked by #44736
mattleibow opened this issue May 25, 2021 · 9 comments
Labels
dotnet An issue or pull request related to .NET (6) dotnet-pri0 .NET 6: required for stable release enhancement The issue or pull request is an enhancement iOS Issues affecting iOS macOS Issues affecting macOS
Milestone

Comments

@mattleibow
Copy link
Contributor

Steps to Reproduce

  1. Create a NuGet package with assets in the runtimes/*/native folder (a .dll on win-x64, a .so on android-arm64 and a .framework in ios)
  2. Install the package into the various apps
  3. Observe the native files get included on Android (with an issue [One .NET] improve native library ABI detection at build time dotnet/android#5432) and on Windows - but not on iOS

I see the PR that brings native bits into apps was merged: #11593. This fixes the ability to use native libs, but since all the other platforms automatically include the files under runtimes, this is a bit unexpected. (#11593)

There is the case where files may get greedily included by the build system, but this is not a big issue because the <PackageReference> element has the ExcludeAssets and IncludeAssets attribute that can be used to control this. (https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets)

Expected Behavior

The native framework /runtimes/ios/native/libSkiaSharp.framework is automatically included into the app.

Actual Behavior

The native framework was not included.

Environment

.NET 6.0

Build Logs

Example Project (If Possible)

@rolfbjarne rolfbjarne added the dotnet An issue or pull request related to .NET (6) label May 25, 2021
@rolfbjarne rolfbjarne added this to the .NET 6 milestone May 25, 2021
@rolfbjarne
Copy link
Member

What do we do if the NuGet includes (or want to include) a static library as well?

In your example the NuGet would ship both of these:

  • runtimes/ios/native/libSkiaSharp.framework
  • runtimes/ios/native/libShiaSharp.a

We must only include one of them in the .app.

@spouliot
Copy link
Contributor

runtimes/ios/native/libSkiaSharp.framework

In theory there should be [DllImport ("libSkiaSharp")] inside the app. In practice it would be possible to have cases where it's a native dependency, including cases where it's loaded dynamically (so otool is not a complete solution either).

runtimes/ios/native/libSkiaSharp.a

That's generally handled with [DllImport ("__Internal")] which is very general and means natively link all .a and let the (native) linker/strip do it's job.

Also that one should not be included in the app bundle but as part of the build. Apple is known to reject them (iirc it depends on where they are located in the bundle).

Incidentally that only makes it harder to detect if both are present - and we can't trust names as you'll often see libX.a and X.framework (and about any possible variation that unicode allows).

We must only include one of them in the .app.

This will likely ends up as a GIGO. We can make a best effort [1] to catch incorrect input but the output validations [2] is out of our hands (not fully documented and changes over time).

[1] like warn about .dylib as they will be refused at submission time
[2] plural - that's both build (native link) time and submission time

@spouliot spouliot added enhancement The issue or pull request is an enhancement iOS Issues affecting iOS macOS Issues affecting macOS dotnet-pri0 .NET 6: required for stable release labels May 25, 2021
@mattleibow
Copy link
Contributor Author

If they include both, then that is up to the library author. If I want to do something fancy, then I need to go back to putting it say in the build folder and use the targets file. Just like if I want to put a bunch of files in the native folder for windows - all the dlls will get copied to the output. If I want to have a proper system, then I would write a targets file to pick one or something.

@spouliot
Copy link
Contributor

If they include both, then that is up to the library author.

Yeah but the reality (what we see today with many nuget) is that many authors don't have (full time) access to Mac, nor automated tests on Mac/devices.

Many things can work fine for the simulator (e.g. bundling a static library) but that won't work for device (or be submittable to Apple). That can be very frustrating as the customer (of that nuget) might only find out very late in his app development cycle (like at submit time) that he needs to file an issue with the nuget author (and yes, we're often in the middle of that).

For other (but similar) reasons I've been thinking of a nuget validation tool/script that would build sim and device apps and check that they build, start (sim or device) and pass a few checks (build time) we know Apple also do. Don't hold your breath as I've been thinking of something similar for 3rd party bindings since I started introspection tests (circa 2012).

@mattleibow
Copy link
Contributor Author

Well a static lib should be linked in directly? Not actually included as a bundle item, right? I would put it there and then the SDK would convert it into a implicit <NativeReference>.

If I want to control where this runs, then I would put this in say ios-x64 or ios-arm64

@spouliot
Copy link
Contributor

Well a static lib should be linked in directly?

That was (re-using) the example :)

Still you can run into projects that ships both libX.a and libX-debug.a (we do for libxamarin) or other variations. Simply linking every .a won't work.

Or, like the original, how do you pick the .a versus an (also supplied) .framework or a .dylib (which would be valid for macOS).

I'm not against the idea of having automatic inclusions :) but it's not as trivial as other platforms (more choices) and the knowledge of what/when/why to use one, over others, is less common.

Not actually included as a bundle item, right?

Guess how we discovered Apple would refuse such bundles ;-)

@mattleibow
Copy link
Contributor Author

One thing that I will say is that the folder is designed for this auto-inclusion. If you don't want it to be included, then you shouldn't use this folder. Just like with putting things in the lib folder - it is auto included in the build. If you want to exclude some dlls, then you put it somewhere else.

@rolfbjarne
Copy link
Member

@mattleibow do you have a test project for this? Or could you create one?

@rolfbjarne
Copy link
Member

I believe this to be the same as #12572 (which is a more general issue), so I'm closing this one in favor of that one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dotnet An issue or pull request related to .NET (6) dotnet-pri0 .NET 6: required for stable release enhancement The issue or pull request is an enhancement iOS Issues affecting iOS macOS Issues affecting macOS
Projects
None yet
Development

No branches or pull requests

3 participants