[NativeAOT] How do I link a static library from a nuget package? #108981
-
In my NativeAOT project, I would like the link the static libraries from |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
It really comes down to specifying DirectPInvoke and NativeLibrary msbuild properties. For specific integrations consumed by .NET itself like ICU - there are separate properties (see https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/compiling.md). Which library do you want to link to? |
Beta Was this translation helpful? Give feedback.
-
I wrote a sample that statically links the https://github.com/AustinWise/DotNetHostingAndNativeAot Drawing on the sample app, instead of using the I tested this solution on Windows 11, Ubuntu 24.04, and macOS 15. On Linux, you might have to do something like I'll reproduce the current state of my solution below: Project file<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<Target Name="PrepareForNativeBuild" AfterTargets="Build">
<PropertyGroup>
<NetHostDir>$(NetCoreTargetingPackRoot)/Microsoft.NETCore.App.Host.$(NETCoreSdkRuntimeIdentifier)/$(BundledNETCoreAppPackageVersion)/runtimes/$(NETCoreSdkRuntimeIdentifier)/native</NetHostDir>
<NetHostName Condition="$([MSBuild]::IsOsPlatform('Windows'))">libnethost.lib</NetHostName>
<NetHostName Condition="!$([MSBuild]::IsOsPlatform('Windows'))">libnethost.a</NetHostName>
</PropertyGroup>
<ItemGroup>
<NativeLibrary Include="$(NetHostDir)/$(NetHostName)" />
</ItemGroup>
<ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows'))">
<!-- This is needed by libnethost.a. -->
<LinkerArg Include="-lstdc++" />
</ItemGroup>
</Target>
</Project> Code fileThis prints the host FXR path: using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
[assembly: DisableRuntimeMarshalling]
partial class Program
{
static void Main()
{
try
{
string hostFxrPath = GetHostFxrPath();
Console.WriteLine($"Got host FXR Path: {hostFxrPath}");
}
catch (Exception ex)
{
Console.WriteLine($"Failed to get host FXR path: {ex.Message}");
}
}
private static string GetHostFxrPath()
{
if (OperatingSystem.IsWindows())
{
char[] buffer = new char[1024];
nint bufferSize = buffer.Length;
int rc = get_hostfxr_path_windows(buffer, ref bufferSize, IntPtr.Zero);
if (rc == 0)
{
return new string(buffer.AsSpan().Slice(0, (int)bufferSize - 1));
}
else
{
throw new Exception($"get_hostfxr_path failed: {rc}");
}
}
else
{
byte[] buffer = new byte[1024];
nint bufferSize = buffer.Length;
int rc = get_hostfxr_path_non_windows(buffer, ref bufferSize, IntPtr.Zero);
if (rc == 0)
{
return Encoding.UTF8.GetString(buffer.AsSpan().Slice(0, (int)bufferSize - 1));
}
else
{
throw new Exception($"get_hostfxr_path failed: {rc}");
}
}
}
[LibraryImport("*", EntryPoint = "get_hostfxr_path")]
private static partial int get_hostfxr_path_windows(char[] buffer, ref nint buffer_size, IntPtr parameters);
[LibraryImport("*", EntryPoint = "get_hostfxr_path")]
private static partial int get_hostfxr_path_non_windows(byte[] buffer, ref nint buffer_size, IntPtr parameters);
} |
Beta Was this translation helpful? Give feedback.
I wrote a sample that statically links the
nethost
API into NativeAOT app. This sample currently only works when published as NativeAOT. If I get more time, I may extend it support dynamic linking so that it can be run as a normal .NET app on CoreCLR.https://github.com/AustinWise/DotNetHostingAndNativeAot
Drawing on the sample app, instead of using the
Microsoft.NETCore.DotNetAppHost
package to get thenethost
library, this app finds thenethost
library from the targeting pack. Typically the .NET SDK includes this.I tested this solution on Windows 11, Ubuntu 24.04, and macOS 15. On Linux, you might have to do something like
apt-get install libstdc++-dev
.I'll reproduce the current state…