Search code examples
nuget.net-standard

Warning when using nuget package that contains native DLL


I am building an ASP.NET Core Web API app which uses a .NET Standard 2.0 library to wrap some C/C++ native libraries. The native libraries are built into platform-specific Win32 .dlls, Linux .so, and MacOS .dylib, etc, and included in the wrapper library as binaries. The NETStandard library detects the user's platform and calls into the appropriate native library and method using P/Invoke. This wrapper library is then published to an internal NuGet package source and referenced from the ASP.NET Core project.

This actually works great and is running as is, but during the build for the ASP.NET project I get a series of warnings related to the underlying native modules:

Warning MSB3246 Resolved file has a bad image, no metadata, or is otherwise inaccessible. Could not load file or assembly 'mylibrary32.dll' or one of its dependencies. The module was expected to contain an assembly manifest.

The native libraries are simply included in the wrapper project and package like so:

<ItemGroup>
  <None Pack="true" PackagePath="lib/netstandard2.0/mylibrary32.dll" Update="mylibrary32.dll">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
  <None Pack="true" PackagePath="lib/netstandard2.0/mylibrary64.dll" Update="mylibrary64.dll">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>      
  ... etc ...
</ItemGroup>

I can ignore the warnings easily enough, but we would ultimately like to be able to distribute this nuget package to customers, and a project reference that immediately introduces scary-looking warnings is not ideal. How can I structure the NETStandard wrapper project/package so that downstream consumers won't try to load those native libraries themselves and generate the warnings?


Solution

  • Native libraries should not be part of the lib folder but packed under the runtimes folder based on the runtime identifier used by .NET core.

    So you'd pack into e.g.

    runtimes/win-x86/native/mylib.dll
    runtimes/win-x64/native/mylib.dll
    runtimes/linux-x64/native/mylib.so
    runtimes/osx-x64/native/mylib.dylib
    …
    

    When consumed from a .NET Core application, these will be put into a runtimes folder and the host will load the appropriate one based on the current runtime identifier. Alternatively, NuGet will choose the right asset for runtime-specific projects, like .NET Framework projects.