.NET AOT Cross-Compilation Toolchain uses the Bootlin cross-compilation toolchains to enable .NET Native AOT builds for multiple Linux architectures. Compilation is performed on an x86_64 host system, which generates native binaries for the selected target RID.
This toolchain consists of two components:
dotnet aotxc- a .NET tool for installing and managing AOT toolchainsdotnet-aot-xc- a shell script that must be sourced to activate the toolchain before publishing
Note
Blazor apps currently do not support the full AOT compilation. You can use the ReadyToRun Compilation instead. Blazor publish samples found in my repos:
Ahead-of-Time (AOT) compilation converts your .NET application directly into a native binary at build time, so no JIT (Just-in-Time) compiler is needed at runtime. This results in:
- Faster startup time - no warm-up phase
- Lower memory usage - no JIT runtime overhead
- Self-contained binaries - no .NET runtime required on the target machine
Note
AOT compilation trades some runtime flexibility (e.g. dynamic code generation) for performance and portability. Not all .NET features are supported - see the .NET Native AOT documentation for compatibility details.
| RID | Arch | Libc | Size (dl/ext) |
|---|---|---|---|
linux-x64 |
x86-64 | glibc | 115 MB/514 MB |
linux-musl-x64 |
x86-64 | musl | 100 MB/444 MB |
linux-arm64 |
aarch64 | glibc | 109 MB/497 MB |
linux-musl-arm64 |
aarch64 | musl | 95 MB/429 MB |
The installation location is $HOME/.dotnet-aot-xc.
Important
This tool is based on the DOTNET_ROOT environment variable to determine the
installation path. Make sure to set DOTNET_ROOT to the desired installation
path before installing the tool.
Check if DOTNET_ROOT is already set:
echo $DOTNET_ROOTIf not set, you can determine the correct value from the dotnet binary location and add it to your .bashrc:
echo "export DOTNET_ROOT=$(dirname $(which dotnet))" >> ~/.bashrcThen source the .bashrc to apply the changes:
source ~/.bashrcVerify that DOTNET_ROOT is set correctly:
echo $DOTNET_ROOTdotnet tool install dotnet-aotxc --tool-path "$DOTNET_ROOT"Uninstall:
dotnet tool uninstall dotnet-aotxc --tool-path "$DOTNET_ROOT"To see the help information, run:
dotnet aotxc --help░░░░█▀█░█▀▀░▀█▀░░░█▀█░█▀█░▀█▀░░░█░█░█▀▀░
░░░░█░█░█▀▀░░█░░░░█▀█░█░█░░█░░░░▄▀▄░█░░░
░▀░░▀░▀░▀▀▀░░▀░░░░▀░▀░▀▀▀░░▀░░░░▀░▀░▀▀▀░
.NET AOT XC Command-line Tools v1.0.0
Variables:
DOTNET_ROOT: $HOME/my/dotnet/path
OS: Arch Linux
Architecture: X64
Libc: Glibc
Usage: dotnet aotxc [command] [options]
Options:
--version Show version information
-h,--help Show help information
-v,--verbose Show verbose output
--no-color Do not colorize output
Commands:
list Lists installed AOT toolchains
install Installs the AOT toolchain
uninstall Uninstalls the AOT toolchain
Use "dotnet aotxc [command] --help" for more information about a command
To list the installed/uninstalled toolchains, run the following command:
dotnet aotxc list[✓] linux-x64
[✓] linux-arm64
[X] linux-musl-x64
[X] linux-musl-arm64
To install the toolchain for a specific RID, run the following command:
dotnet aotxc install --helpUsage: dotnet aotxc install [RID] [options]
Options:
--version Show version information
-h,--help Show help information
-v,--verbose Show verbose output
--no-color Do not colorize output
RID:
linux-x64 Install AOT toolchain for Linux x64 glibc
linux-arm64 Install AOT toolchain for Linux arm64 glibc
linux-musl-x64 Install AOT toolchain for Linux x64 musl
linux-musl-arm64 Install AOT toolchain for Linux arm64 musl
To uninstall the toolchain for a specific RID, run the following command:
dotnet aotxc uninstall --helpUsage: dotnet aotxc uninstall [RID] [options]
Options:
--version Show version information
-h,--help Show help information
-v,--verbose Show verbose output
--no-color Do not colorize output
RID:
linux-x64 Uninstall AOT toolchain for Linux x64 glibc
linux-arm64 Uninstall AOT toolchain for Linux arm64 glibc
linux-musl-x64 Uninstall AOT toolchain for Linux x64 musl
linux-musl-arm64 Uninstall AOT toolchain for Linux arm64 musl
Add these PropertyGroups to your .pubxml or .csproj:
Note
Adjust the <PublishDir> paths to match your project structure and preferred
output location before publishing.
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<PublishAot>true</PublishAot>
<Toolchains Condition="$([MSBuild]::IsOSPlatform('Linux'))">$(HOME)/.dotnet-aot-xc</Toolchains>
</PropertyGroup>
<!-- linux-x64 (glibc) -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' AND '$(Toolchains)' != ''">
<PublishDir>../publish/linux-x64</PublishDir>
<CppCompilerAndLinker>x86_64-linux-gcc</CppCompilerAndLinker>
<SysRoot>$(Toolchains)/linux-x64/x86_64-buildroot-linux-gnu/sysroot</SysRoot>
<ObjCopyName>x86_64-buildroot-linux-gnu-objcopy</ObjCopyName>
</PropertyGroup>
<!-- linux-arm64 (glibc) -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-arm64' AND '$(Toolchains)' != ''">
<PublishDir>../publish/linux-arm64</PublishDir>
<CppCompilerAndLinker>aarch64-linux-gcc</CppCompilerAndLinker>
<SysRoot>$(Toolchains)/linux-arm64/aarch64-buildroot-linux-gnu/sysroot</SysRoot>
<ObjCopyName>aarch64-buildroot-linux-gnu-objcopy</ObjCopyName>
</PropertyGroup>
<!-- linux-musl-x64 -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' AND '$(Toolchains)' != ''">
<PublishDir>../publish/linux-musl-x64</PublishDir>
<CppCompilerAndLinker>x86_64-linux-musl-gcc</CppCompilerAndLinker>
<SysRoot>$(Toolchains)/linux-musl-x64/x86_64-buildroot-linux-musl/sysroot</SysRoot>
<ObjCopyName>x86_64-buildroot-linux-musl-objcopy</ObjCopyName>
</PropertyGroup>
<!-- linux-musl-arm64 -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-musl-arm64' AND '$(Toolchains)' != ''">
<PublishDir>../publish/linux-musl-arm64</PublishDir>
<CppCompilerAndLinker>aarch64-linux-musl-gcc</CppCompilerAndLinker>
<SysRoot>$(Toolchains)/linux-musl-arm64/aarch64-buildroot-linux-musl/sysroot</SysRoot>
<ObjCopyName>aarch64-buildroot-linux-musl-objcopy</ObjCopyName>
</PropertyGroup>
</Project>Before publishing, you need to activate the toolchain for the target RID using the source dotnet-aot-xc <rid> command. This sets up the necessary environment variables for MSBuild to use the correct compiler, linker, and sysroot for cross-compilation.
Important
The dotnet-aot-xc script must be sourced, not executed directly. If you run dotnet-aot-xc directly, it will show help information instead of activating the toolchain.
Activate toolchain and build for linux-x64:
source dotnet-aot-xc linux-x64Then, run the publish command:
dotnet publish -p:PublishProfile=Release.pubxml -r linux-x64Activate toolchain and build for linux-arm64:
source dotnet-aot-xc linux-arm64Then, run the publish command:
dotnet publish -p:PublishProfile=Release.pubxml -r linux-arm64Activate toolchain and build for linux-musl-x64:
source dotnet-aot-xc linux-musl-x64Then, run the publish command:
dotnet publish -p:PublishProfile=Release.pubxml -r linux-musl-x64Activate toolchain and build for linux-musl-arm64:
source dotnet-aot-xc linux-musl-arm64Then, run the publish command:
dotnet publish -p:PublishProfile=Release.pubxml -r linux-musl-arm64