Regression: .NET 10 Native AOT build fails for WinUI 3 via .wapproj on cross-arch CI (x64 host -> ARM64 target)
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 1.3k
- PR merge metrics
- PR metrics pending
Description
### Describe the bug
In .NET 10.0.103, it fails to publish a Native AOT-enabled WinUI 3 application using a .wapproj when the host architecture (x64) differs from the target architecture (ARM64). This worked in .NET 9.
### To Reproduce
1. On an x64 machine with .NET 10.0.103 SDK installed.
2. Create a WinUI 3 app with PublishAot=true.
3. Add a .wapproj (Windows Application Packaging Project) referencing the WinUI 3 app.
4. Run: dotnet publish MyWapProj.wapproj /p:Platform=arm64 /p:Configuration=Release /p:PublishAot=true
5. Result: Build fails because the compiler cannot find the ARM64 runtime artifacts (CoreLib, symbols, etc.) as the SDK fails to resolve/download the win-arm64 runtime pack.
#### Expected Behavior:
The SDK should automatically resolve and "Restore" the required Microsoft.NETCore.App.Runtime.NativeAOT.win-arm64 runtime pack when a cross-architecture RID is specified, even when the build is initiated via .wapproj.
#### Actual Behavior:
RuntimePackagePath remains empty, and the build fails with errors indicating that the compiler cannot find the runtime-specific libraries.
### Exceptions (if any)
```
##[error]C:\Users\cloudtest.nuget\packages\microsoft.dotnet.ilcompiler\10.0.3\build\Microsoft.NETCore.Native.Publish.targets(70,5): Error : The PrivateSdkAssemblies ItemGroup is required for _ComputeAssembliesToCompileToNative
```
### Further technical details
Based on diagnostic logs, the failure stems from a change in how the Native AOT toolchain is distributed in .NET 10. The runtime-specific bits (native DLLs, framework libs) have moved from the Microsoft.DotNet.ILCompiler NuGet package into SDK Runtime Packs (Microsoft.NETCore.App.Runtime.NativeAOT.*).
Missing Property Population: The ImportRuntimeIlcPackageTarget target, which is responsible for populating RuntimePackagePath from @(ResolvedILCompilerPack), does not seem to execute or resolve correctly when triggered from a .wapproj context.
Broken Workaround: Previously, setting PublishAotUsingRuntimePack=false allowed the compiler to look in the NuGet package. In .NET 10, this property is effectively broken for this scenario because the runtimes/ directory no longer exists in the ILCompiler NuGet package.
#### Temp Workaround
In both the WinUI 3 .csproj and the .wrapproj files, add specific NAOT runtime pacakges:
```
```
Then run dotnet restore to download the NAOT runtime packs:
```pwsh
foreach ($rid in @("win-x64", "win-arm64")) {
foreach ($proj in $projects) {
$name = [System.IO.Path]::GetFileName($proj)
Write-Host "Restoring $name for $rid"
dotnet restore $proj --configfile $configFile -r $rid
}
}
```
Finally use the following target file to fill in missing path vars:
```
<_IlcPackageVersion>$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(ILCompilerTargetsPath))))))) <_NativeAotRuntimePackBase>$(NuGetPackageRoot)microsoft.netcore.app.runtime.nativeaot.$(RuntimeIdentifier)$([System.IO.Path]::DirectorySeparatorChar)$(_IlcPackageVersion)$([System.IO.Path]::DirectorySeparatorChar)runtimes$([System.IO.Path]::DirectorySeparatorChar)$(RuntimeIdentifier)$([System.IO.Path]::DirectorySeparatorChar)
$(_NativeAotRuntimePackBase)native$([System.IO.Path]::DirectorySeparatorChar)
$(_NativeAotRuntimePackBase)native$([System.IO.Path]::DirectorySeparatorChar)
$(_NativeAotRuntimePackBase)lib$([System.IO.Path]::DirectorySeparatorChar)net10.0$([System.IO.Path]::DirectorySeparatorChar)
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.