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

Architecture-specific folders like runtimes/<rid>/native/ outside of NuGet packages [nativeinterop] #24708

Open
KiruyaMomochi opened this issue Apr 5, 2022 · 1 comment
Assignees
Labels
Area-NetSDK native-assets Issues related to how the SDK should deal with Native assets untriaged Request triage from a team member

Comments

@KiruyaMomochi
Copy link

KiruyaMomochi commented Apr 5, 2022

Problem

I am trying to build a project with native libraries P/Invoke.
Since the project is for multiple architectures, I hope dotnet can find the right library automatically after I include them.

However, the only way I can find is to create a NuGet package, putting these files in architecture-specific folders
(RID-specfic folders), then add the package reference to the project. If I directly put runtimes/<rid>/native/ in the project or add project reference to another project containing this folder, dotnet cannot find the library.

When architecture-specific folders take effect, path to these native libraries can be found at <AssemblyName>.deps.json.

Side story: Xamarin and Blazor WebAssembly

In Xamarin, both iOS/Catalyst and Android supports architecture-specific folders in NuGet packages now. Out of NuGet package, their behavior is the same as dotnet. However, they do provide a MSBuild item to include a native library: PackageReference for iOS/Catalyst (not documented yet), AndroidNativeLibrary for Android.

In WebAssembly, these dependencies aren't referenced automatically and must be referenced manually as NativeFileReferences. For NuGet package, author can choose to include a .props file in the package.

Suggested Solution

Goal

Taken from #19929, the following goals should be achieved:

  • User can define architecture-specifics asset in a library or application project without packaging (not NuGet package)
  • Project reference should be able to consume library with architecture-specific assets correctly
  • Such specific assets from all sources (app project itself, project references and package references) are
    • correctly copied to the output (for portable apps into runtime subdirectory, for RID specific apps into the root) and
    • the correct .deps.json is produced.

This behavior may not be default for a new project, but developers can make use of it by setting some properties.

MSBuild file

Reference native library

To support architecture-specific native libraries, we should at least provide a MSBuild item, which can be used to reference a library. For example, NativeFileReferences.

<ItemGroup>
  <NativeFileReferences Include="runtimes/win-x64/native/MyGrimoire.dll" RuntimeIdentifier="win-x64" />
  <NativeFileReferences Include="runtimes/<rid>/native/<AssemblyName>.dll" RuntimeIdentifier="<rid>" />
</ItemGroup>

For a unified experience, this item should also be available to Xamarin.iOS, Xamarin.Android and Blazor WebAssembly, although they can also choose to use their own item when some special feature is required.

Implictly include all architecture-specific items

To support architecture-specific folders, we may provide a true/false property. For example, a property called EnableArchitectureSpecificItems.

<PropertyGroup>
  <EnableArchitectureSpecificItems>true</EnableArchitectureSpecificItems>
</PropertyGroup>

When the property is set, all files in architecture-specific folders will behave as if referencing a package containing these files.

CLI support

We should also make our CLI supports adding these native references.

dotnet add reference 'cool.dylib' --rid 'osx-x64'

When invoking this command, NativeFileReferences will be added to the project.

Documention

We should document it in Native Interoperability part of .NET Docs, explaining this convention and how to use them. We may also remind user possible divergence between other platforms like Xamarin or WebAssembly.

Additional Context

There are many releated issues (some are not active), and it's hard to understand how rid-specific folder works without knowing NuGet, MSBuild and difference between package/project references. Adding Xamarin and WebAssembly, it is much harder.

That's why I created this feature request, trying to collect all these discussions and try to make it clear. Below are some discussions I have found.

Interesting discovery

I don't know if it's expected behavior or not, but if there are some NuGet libraries already using these rid-specific folders (like SkiaSharp.NativeAssets.*), and you put your own library in these folder too, then your libraries can also be found.

@asmichi
Copy link

asmichi commented Jun 12, 2022

Some more links:

@baronfel baronfel added the native-assets Issues related to how the SDK should deal with Native assets label Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-NetSDK native-assets Issues related to how the SDK should deal with Native assets untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

3 participants