StuDev.AotAnywhere
1.0.4
dotnet add package StuDev.AotAnywhere --version 1.0.4
NuGet\Install-Package StuDev.AotAnywhere -Version 1.0.4
<PackageReference Include="StuDev.AotAnywhere" Version="1.0.4" />
<PackageVersion Include="StuDev.AotAnywhere" Version="1.0.4" />
<PackageReference Include="StuDev.AotAnywhere" />
paket add StuDev.AotAnywhere --version 1.0.4
#r "nuget: StuDev.AotAnywhere, 1.0.4"
#:package StuDev.AotAnywhere@1.0.4
#addin nuget:?package=StuDev.AotAnywhere&version=1.0.4
#tool nuget:?package=StuDev.AotAnywhere&version=1.0.4
AotAnywhere
Cross-compile Native AOT .NET apps to Linux, macOS and Windows — from any of them.
PublishAot normally refuses to build for another OS:
$ dotnet publish -r linux-x64
Microsoft.NETCore.Native.Publish.targets(59,5): error : Cross-OS native compilation is not supported.
AotAnywhere is a NuGet package that lifts that restriction. Add it to your
project and dotnet publish -r <rid> just works for Linux, macOS and Windows
RIDs, from a Windows, macOS or Linux machine. It uses Zig
as the linker and sysroot, and brings everything it needs with it — no extra
SDKs, cross toolchains or system packages to install on the build machine.
<p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="docs/assets/platform-matrix-dark.svg"> <img alt="Diagram: builds on Windows (x64, x86), macOS (arm64, x64) and Linux (x64, arm64) hosts, through AotAnywhere (dotnet publish -r <rid>), and runs on Linux glibc and musl (x64, arm64, arm), macOS (osx-arm64, osx-x64) and Windows (win-x64, win-arm64). Every combination is CI-tested: 5 hosts × 10 target RIDs." src="docs/assets/platform-matrix-light.svg" width="880"> </picture> </p>
Quick start
In a project that already uses Native AOT, add an
Sdkreference toStuDev.AotAnywhereinside the<Project>element:<Project Sdk="Microsoft.NET.Sdk"> <Sdk Name="StuDev.AotAnywhere" Version="1.0.4" />(Or omit the
Versionand pin it once inglobal.jsonundermsbuild-sdks.)Publish for one of the newly available RIDs:
dotnet publish -r linux-x64 # or linux-arm64, linux-arm* dotnet publish -r linux-musl-x64 # or linux-musl-arm64, linux-musl-arm* dotnet publish -r osx-x64 # or osx-arm64 dotnet publish -r win-x64 # or win-arm64
That's it — no other tools required, including symbol stripping (the package handles that itself, no LLVM install needed).
Why an
Sdkreference and not aPackageReference? The package pulls in its Zig linker toolchain through a second, host-specific NuGet package, and NuGet cannot restore package references declared inside a package's build targets (NuGet/Home#4790). SDK props are evaluated during restore, so theSdkform fetches everything the first time with no further setup. A plainPackageReferencestill works if you restore Zig yourself — see Advanced configuration.
Supported platforms
Host machines (where you run dotnet publish):
- Windows (x86, x64)
- macOS (x64, arm64)
- Linux (x64, arm64)
Targets (what you can publish for), from any supported host:
| Target | RIDs | Notes |
|---|---|---|
| Linux | linux-x64, linux-arm64, linux-arm, linux-musl-x64, linux-musl-arm64, linux-musl-arm |
glibc and musl. The arm/ARMv7 RIDs require a net9.0+ target framework. |
| macOS | osx-x64, osx-arm64 |
Links against bundled Apple linker stubs. See macOS targets. |
| Windows | win-x64, win-arm64 |
From Linux/macOS hosts, via zig's MinGW-w64 import libraries. On a Windows host the SDK links these natively with MSVC. See Windows targets. |
Things to be aware of
ARMv7 needs .NET 9+. The
linux-armandlinux-musl-armtargets require anet9.0or later target framework — .NET only ships ILCompiler runtime packs for them from .NET 9 onwards.macOS binaries need signing before you distribute them. Out of the box the output only runs locally (osx-arm64 gets an ad-hoc signature, osx-x64 is unsigned). To hand it to other people you must sign it with a Developer ID certificate and notarize it — both doable from any host, no Mac required. See Signing and notarizing.
Windows output skips some MSVC hardening. Control Flow Guard and CET markers (
/CETCOMPAT) are not carried over. For maximum-hardening release builds, link on Windows with MSVC. Details in Windows targets.Windows on ARM64 is not supported as a host. zig 0.16's aarch64-windows code generation is broken, so Zig can't reliably run there. It will be revisited when a newer Zig fixes it. (win-arm64 as a target is fully supported.)
Linux ICU dependency. A cross-compiled binary may need the ICU library on the target machine, the same as any globalization-enabled .NET app. See Runtime dependencies on Linux below.
Runtime dependencies on target Linux systems
When running the cross-compiled binaries on Linux, you may hit a missing ICU library:
Process terminated. Couldn't find a valid ICU package installed on the system. Please install libicu (or icu-libs) using your package manager and try again.
Solution 1 (recommended): install ICU on the target system:
# Ubuntu/Debian
sudo apt-get install libicu-dev
# CentOS/RHEL/Fedora
sudo yum install libicu-devel # or: sudo dnf install libicu-devel
# Alpine Linux
sudo apk add icu-libs
Solution 2: build with invariant globalization (no ICU dependency):
dotnet publish -r linux-x64 /p:InvariantGlobalization=true
Note that invariant globalization disables culture-specific formatting, sorting, and other globalization features.
Documentation
- macOS targets — Apple linker stubs, and signing & notarizing for distribution
- Windows targets — how win-x64/win-arm64 cross-linking works
- Advanced configuration — how linking works (MSBuild takeovers + managed tasks), and using your own Zig
- Cross-platform validation — the CI matrix that tests every host → target combination
Credits
AotAnywhere began as a fork of Michal Strehovsky's
PublishAotCross, which
first demonstrated that Zig could stand in as the linker and sysroot to make
Native AOT cross-compilation work. It has since been substantially rewritten —
the native shim is gone, links run directly through zig cc and managed MSBuild
tasks, and it ships bundled Apple sysroot stubs, symbol stripping, and a full
host × target CI matrix — but the original insight and inspiration are Michal's.
Thank you.
License
MIT — see LICENSE.TXT.
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 |
|---|---|---|
| 1.0.4 | 225 | 7/11/2026 |
| 1.0.3 | 99 | 7/10/2026 |
| 1.0.2 | 104 | 7/10/2026 |
| 1.0.1 | 98 | 7/9/2026 |
| 1.0.0 | 130 | 7/6/2026 |
| 1.0.0-preview.2 | 78 | 7/6/2026 |
| 1.0.0-preview.1 | 66 | 7/6/2026 |