Search code examples
c#.net-corenugetcross-platformnuspec

multi-platform native libraries in C# nuspec


We have a C# project (.net Core) which is cross-platform. It uses native libraries (C++), which are different for each platform.

We know that you can specify different frameworks in a single nuspec file, but this case is different:

  • There will be a single C# DLL file
  • There will be different native libraries (like a.linux.so and a.windows.dll)

We want be able to install only the libraries that are pertinent to a specific OS.

What is the recommended mechanism?


Solution

  • First, make sure you are using SDK-based projects to ensure you get correct dependency trimming for target frameworks like netstandard* (instead of using a .nuspec file).

    The goal is to separate your native runtime assets into a runtimes subfolder inside your NuGet folder so that the layout is:

    \lib\YourManagedCode.dll
    \runtimes\win-x86\native\some.dll
    \runtimes\win-x64\native\some.dll
    \runtimes\linux-x64\native\libsome.so
    \runtimes\osx-x64\native\some.dylib
    

    An example project file could look like this, assuming you already have runtimes folder:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
      </PropertyGroup>
      <ItemGroup>
        <None Update="runtimes\**" Pack="true" PackagePath="runtimes" />
      </ItemGroup>
    </Project>
    

    If you need to test locally, you can also add CopyToOutputDirectory="PreserveNewest" to ensure the files are copied to the output. .NET Core should be able to resolve files located in runtimes directories for methods annotated with [DllImport("some")].

    The resulting NuGet package can be referenced from both .NET Core and .NET Framework projects. If some "RID-fallback" (e.g. win10-x64 => win-x64) does not work on .NET Framework projects, make sure this project also references a recent version of the Microsoft.NETCore.Platforms package (it provides NuGet with a graph of known values, has nothing much to do with .NET Core itself..).