Asmichi.InjectNativeFileDepsHack 0.2.0

dotnet add package Asmichi.InjectNativeFileDepsHack --version 0.2.0                
NuGet\Install-Package Asmichi.InjectNativeFileDepsHack -Version 0.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Asmichi.InjectNativeFileDepsHack" Version="0.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Asmichi.InjectNativeFileDepsHack --version 0.2.0                
#r "nuget: Asmichi.InjectNativeFileDepsHack, 0.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Asmichi.InjectNativeFileDepsHack as a Cake Addin
#addin nuget:?package=Asmichi.InjectNativeFileDepsHack&version=0.2.0

// Install Asmichi.InjectNativeFileDepsHack as a Cake Tool
#tool nuget:?package=Asmichi.InjectNativeFileDepsHack&version=0.2.0                

Asmichi.InjectNativeFileDepsHack

An insane hack to inject runtime assets into deps.json by injecting RuntimeTargetsCopyLocalItems items into the GenerateDepsFile task.

This library can be obtained via NuGet.

Background

By default (without DllImportSearchPath.AssemblyDirectory), the .NET runtime only loads native DLLs listed in the deps.json of an application. There is a long-standing issue: deps.json does not list native DLLs from reference projects (only native DLLs from NuGet packages), which means that such native DLLs cannot be loaded:

So, if you develop a library containing native DLLs, you get stuck. The test projects and sample projects will project-reference the library project, which does not work!

WARNING

Again, this is an insane hack that plays with the implementation details deep inside the .NET SDK. It is likely that this will break even by a minor version update of the .NET SDK.

Tested on the following versions of the .NET SDK:

  • 6.0.301

Usage

List the native files as InjectNativeFileDepsHack items in your application project (not your library project).

Notes:

  • Normally you list the native DLLs as Content items in the library project, so the native DLLs should be copied into $(OutputPath).
  • You cannot use wildcards in Include to list files within output directories because these wildcards are evaluated before the build starts and thus output files are not yet built (such a wildcard will break clean builds).
  <ItemGroup>
    <PackageReference Include="Asmichi.InjectNativeFileDepsHack" Version="0.2.0" PrivateAssets="all" IncludeAssets="runtime;build;native;contentfiles;analyzers" />
  </ItemGroup>

  <ItemGroup>
    <InjectNativeFileDepsHack Include="$(OutputPath)runtimes\linux-x64\native\libMyAwesomeLibrary.so">
      
      <DestinationSubDirectory>runtimes\linux-x64\native</DestinationSubDirectory>
      
      <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    </InjectNativeFileDepsHack>
  </ItemGroup>

Appendices

Example

See sample for a minimal example. To run the sample, on an x64 Linux system, run:

(cd sample; ./build_and_run.sh)

Real-world example

See https://github.com/asmichi/ChildProcess/blob/master/build/msbuild/InjectChildProcessNativeFileDeps.targets and its usage.

How Asmichi.InjectNativeFileDepsHack works

Basically, it tricks the deps.json generation process into treating the specified native DLLs as the runtime assets of the Asmichi.InjectNativeFileDepsHack NuGet library.

The runtimeTargets items (assetType == native) of a library comes from RuntimeLibray.NativeLibraryGroups. Looking into the target, GenerateDepsFile and DependencyContextBuilder for clues of how NativeLibraryGroups are collected, you will notice that a project type library always have empty NativeLibraryGroups. So, there is no way to add runtimeTargets items into a project type library. Absolutely no way! Only NuGet libraries!

NuGet runtime files are collected by ResolvePackageAssets as RuntimeTargetsCopyLocalItems. Asmichi.InjectNativeFileDepsHack adds the specified native DLLs as RuntimeTargetsCopyLocalItems items just before GenerateDepsFile runs, hence they appear as runtimeTargets items of the Asmichi.InjectNativeFileDepsHack NuGet library.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.0 292 5/2/2023
0.1.0 304 7/2/2022