NativeSdk 0.5.2
<Sdk Name="NativeSdk" Version="0.5.2" />
#:sdk NativeSdk@0.5.2
NativeSdk
A MSBuild SDK package for building Native AOT applications and libraries with C#.
Requirements
- .NET 8.0 or later
Installation
Use NativeSdk as your project SDK:
<Project Sdk="NativeSdk/0.5.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>
This SDK automatically inherits from Microsoft.NET.Sdk, so you don't need to specify it separately.
Features
This SDK automatically configures your project with:
Common Settings (All Project Types)
| Setting | Default Value | Description |
|---|---|---|
OutputType |
Exe |
Builds as executable by default |
PublishAot |
true |
Enables Native AOT compilation |
IsAotCompatible |
true |
Marks the project as AOT compatible |
AllowUnsafeBlocks |
true |
Enables unsafe code |
TrimMode |
full |
Full trimming for size optimization |
InvariantGlobalization |
true |
Invariant globalization mode |
EnableTrimAnalyzer |
true |
Enables trim compatibility analyzer |
EnableAotAnalyzer |
true |
Enables AOT compatibility analyzer |
TreatWarningsAsErrors |
true |
Treats warnings as errors |
Default Using Namespaces
The following namespaces are automatically included for Interop scenarios:
| Namespace | Description |
|---|---|
System.Runtime.InteropServices |
Core interop types ([DllImport], [UnmanagedCallersOnly], Marshal) |
System.Runtime.InteropServices.Marshalling |
Source-generated marshalling ([LibraryImport]) |
System.Runtime.CompilerServices |
Compiler services ([SkipLocalsInit], Unsafe) |
System.Buffers |
Buffer operations (Span<T>, Memory<T>) |
Library-Specific Settings
When OutputType is set to Library, the following additional settings are applied:
| Setting | Default Value | Description |
|---|---|---|
NativeLib |
Shared |
Builds as a shared/dynamic library (can be overridden to Static) |
DnneGenerateExports |
true |
DNNE export generation enabled |
DnneBuildExports |
false |
DNNE build exports disabled |
Debug Configuration
- Stack trace support enabled
- Metadata preserved for debugging
Release Configuration
- Stack trace support disabled
- Metadata trimmed for smaller binaries
Usage Examples
Building a Native Executable (Default)
<Project Sdk="NativeSdk/0.5.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>
Building a Shared Library (DLL/SO)
<Project Sdk="NativeSdk/0.5.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>
</Project>
Building a Static Library
<Project Sdk="NativeSdk/0.5.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
<NativeLib>Static</NativeLib>
</PropertyGroup>
</Project>
Pointer-based QuickSort
This example demonstrates using unsafe pointers with stackalloc for high-performance sorting:
unsafe
{
const int ArraySize = 10;
// Allocate memory on the stack using stackalloc
int* arr = stackalloc int[ArraySize];
// Initialize array with random values
Random rand = new(42);
Console.WriteLine("Before sorting:");
for (int i = 0; i < ArraySize; i++)
{
arr[i] = rand.Next(1, 100);
Console.Write($"{arr[i]} ");
}
Console.WriteLine();
// Execute QuickSort
QuickSort(arr, 0, ArraySize - 1);
// Print sorted result
Console.WriteLine("\nAfter sorting:");
for (int i = 0; i < ArraySize; i++)
{
Console.Write($"{arr[i]} ");
}
Console.WriteLine();
static void QuickSort(int* arr, int left, int right)
{
if (left >= right) return;
int pivotIndex = Partition(arr, left, right);
QuickSort(arr, left, pivotIndex - 1);
QuickSort(arr, pivotIndex + 1, right);
}
static int Partition(int* arr, int left, int right)
{
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++)
{
if (arr[j] <= pivot)
{
i++;
(arr[i], arr[j]) = (arr[j], arr[i]); // Tuple swap
}
}
(arr[i + 1], arr[right]) = (arr[right], arr[i + 1]);
return i + 1;
}
}
DNNE Integration
This SDK includes DNNE for generating native exports when building as a library. Use the [UnmanagedCallersOnly] attribute to export functions:
public static class NativeExports
{
[UnmanagedCallersOnly(EntryPoint = "add")]
public static int Add(int a, int b) => a + b;
}
Note: DNNE is only included when
OutputTypeis set toLibrary. TheSystem.Runtime.InteropServicesnamespace is already included by default.
Customization
All settings can be overridden in your project file:
<PropertyGroup>
<OutputType>Library</OutputType>
<NativeLib>Static</NativeLib>
<IlcOptimizationPreference>Size</IlcOptimizationPreference>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
Building
dotnet publish -c Release -r win-x64
dotnet publish -c Release -r linux-x64
dotnet publish -c Release -r osx-arm64
License
MIT
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.