Skip to content

Enable same-OS cross-arch NativeAOT builds; cross-build arm64 AoT legs on x64 - #55205

Merged
baronfel merged 2 commits into
mainfrom
baronfel-cross-arch-nativeaot-legs
Jul 14, 2026
Merged

baronfel merged 2 commits into
mainfrom
baronfel-cross-arch-nativeaot-legs

Conversation

@baronfel

@baronfel baronfel commented Jul 8, 2026

Copy link
Copy Markdown
Member

Follow-up to merged #55143 (issue #55077). Builds directly on that PR.

Motivation

Post-merge review feedback from @akoeplinger on src/Layout/Directory.Build.props:

I think we can remove the '$(TargetRid)' == '$(HostRid)' here to enable windows/osx cross builds

The original gate only allowed NativeAOT cross-compilation for Linux (via the azurelinux cross containers). This PR generalizes the gate so same-OS cross-architecture AoT publishes work on Windows and macOS as well, then uses x64 hardware to cross-build the arm64 AoT legs.

Gate generalization (src/Layout/Directory.Build.props)

Replaces the Linux-only _DotnetAotIsLinuxNativeBuild / _DotnetAotIsLinuxCrossBuild with OS-agnostic properties:

  • _DotnetAotIsSameOSBuild — target OS (from the TargetRid prefix) equals the build host OS. NativeAOT can only target the host OS, so this is the prerequisite for both native and cross publishing.
  • _DotnetAotIsNativeBuild — same OS and TargetArchitecture == BuildArchitecture (the canonical native signal on all platforms; avoids the TargetRid == HostRid mismatch on Linux where HostRid is distro-specific). Keeps the linux-musl and source-build exclusions.
  • _DotnetAotIsCrossBuild — same OS but TargetArchitecture != BuildArchitecture. Covers win-x64→win-arm64, osx-x64→osx-arm64, and Linux (which keeps its CrossBuild + ROOTFS_DIR container semantics).

_ShouldPublishDotnetAot = _DotnetAotTargetRidSupported AND (_DotnetAotIsNativeBuild OR _DotnetAotIsCrossBuild). The strict TargetRid == HostRid clause is removed but the native same-arch/same-OS case remains equivalent. Cross-OS builds, linux-musl, source-build and unsupported RIDs are still excluded (verified by evaluating the gate across 10 scenarios).

GenerateLayout.targets now forwards CrossBuild=true;TargetArchitecture;TargetRid to the child dotnet-aot Publish for all cross-arch builds, not just Linux. sdk-build.yml forwards osProperties to the Windows build step (default empty, no-op for existing legs) so cross legs can pass /p:CrossBuild=true.

macOS: x64 cross-build + arm64 Helix tests (no coverage loss)

Because runTests dispatches tests to Helix (-test /p:CustomHelixTargetQueue=...), AoT test execution is bound to the Helix queue, not the build agent. The macOS AoT leg now builds osx-arm64 on the x64 macOS pool (the Official osx-arm64 leg already cross-builds there) with /p:CrossBuild=true, and still runs the *.AoT.Tests on the osx.15.arm64 Helix queue — so there is zero macOS AoT test-coverage loss.

Windows: new build-only win-arm64 AoT leg

Adds a win-arm64 AoT cross leg that builds on the existing win-x64 pool with /p:CrossBuild=true and publishes the mstat/dgml size-analysis artifacts (gated on runAoTTests). It is build-only (runTests: false) because there is no wired windows arm64 Helix queue yet; running the AoT tests on arm64 hardware is a follow-up pending a windows.11.arm64 queue. Expressed directly in .vsts-ci.yml/.vsts-pr.yml (with the .open queue suffix for PR), mirroring the linux-arm64 cross leg precedent. Existing linux x64/arm64 AoT legs are unchanged.

Validation

This is a Windows dev host, so the actual cross-links can't be exercised locally. All edited YAML/props/targets parse, and the gate's boolean logic was evaluated with MSBuild across native/cross/cross-OS/musl/source-build/unsupported-RID scenarios — all correct. Per @akoeplinger's caveat, a full VMR build is advisable to validate the win-x64→win-arm64 and osx-x64→osx-arm64 cross-links end to end.

…s on x64

Generalize the dotnet-aot NativeAOT publish gate so same-OS cross-architecture
AoT publishes work on Windows and macOS too, not just Linux, per post-merge
review feedback on #55143 (issue #55077).

- src/Layout/Directory.Build.props: replace the Linux-only native/cross gate
  properties with OS-agnostic _DotnetAotIsSameOSBuild / _DotnetAotIsNativeBuild /
  _DotnetAotIsCrossBuild. _ShouldPublishDotnetAot now publishes for a supported
  RID whenever the target OS equals the host OS and the target arch either
  matches (native) or differs (cross) from the build host. Removes the strict
  TargetRid == HostRid clause while preserving native same-arch behavior.
- src/Layout/redist/targets/GenerateLayout.targets: forward
  CrossBuild/TargetArchitecture/TargetRid to the child dotnet-aot Publish for all
  cross-arch builds (win/osx/linux), not just Linux. Comments updated.
- eng/pipelines/templates/jobs/sdk-build.yml: forward osProperties to the Windows
  build step so cross legs can pass /p:CrossBuild=true (no-op for existing legs).
- .vsts-ci.yml / .vsts-pr.yml: macOS AoT leg now cross-builds osx-arm64 on the x64
  macOS pool and still dispatches *.AoT.Tests to the osx.15.arm64 Helix queue (no
  coverage loss). New build-only win-arm64 AoT cross leg on the win-x64 pool that
  publishes the mstat/dgml size-analysis artifacts; Helix arm64 testing deferred
  pending a windows.11.arm64 queue.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 8, 2026 18:46
@baronfel
baronfel requested a review from akoeplinger July 8, 2026 18:49
@baronfel baronfel added Area-Infrastructure Area-dotnet AOT Items that are part of the dotnet CLI AOT-ification effort labels Jul 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR generalizes the dotnet-aot publish gate and CI configuration to enable same-OS cross-architecture NativeAOT builds (win-x64→win-arm64, osx-x64→osx-arm64, and existing linux-x64→linux-arm64 via cross containers). It updates the Layout gating properties and ensures cross-build inputs are forwarded to the dotnet-aot publish step, then wires new/updated pipeline legs to cross-build arm64 AoT outputs on x64 hardware.

Changes:

  • Generalize _ShouldPublishDotnetAot gating in src/Layout/Directory.Build.props from Linux-only to same-OS native vs cross-arch builds.
  • Forward CrossBuild/TargetArchitecture/TargetRid to the dotnet-aot child publish for all same-OS cross-arch builds.
  • Update CI/PR pipelines to add a Windows win-arm64 AoT cross-build leg and switch macOS AoT to cross-build on x64 while still running tests on arm64 Helix.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Layout/redist/targets/GenerateLayout.targets Forward cross-build properties to dotnet-aot publish for same-OS cross-arch builds.
src/Layout/Directory.Build.props Replace Linux-specific AoT publish gating with OS-agnostic same-OS native/cross-arch gating.
eng/pipelines/templates/jobs/sdk-build.yml Allow OS-specific MSBuild property passthrough (osProperties) on Windows build steps.
.vsts-pr.yml Add win-arm64 AoT cross-build leg; switch macOS AoT leg to cross-build on x64 and keep Helix arm64 tests.
.vsts-ci.yml Mirror PR pipeline changes for internal CI (win-arm64 AoT cross-build; macOS AoT cross-build on x64).

Comment thread src/Layout/Directory.Build.props Outdated
The generalized _DotnetAotIsCrossBuild matched the regular linux-arm64 TestBuild
leg (x64 host, arm64 target, same OS) even though that leg builds on the plain
x64 pool with no arm64 sysroot, causing the dotnet-aot NativeAOT cross-link to
fail. On Linux the cross toolchain + target sysroot only exist inside the
azurelinux cross-prereq container, which signals its availability via
CrossBuild=true. Re-add that guard for Linux targets only; Windows/macOS still
infer cross from the architecture mismatch since their toolchains are
multi-target.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@baronfel

Copy link
Copy Markdown
Member Author

This appears to have worked - I checked the legs and each generated NAOT binaries and uploaded the size analysis artifacts.

Comment thread .vsts-ci.yml
@baronfel
baronfel merged commit 5ef6b4b into main Jul 14, 2026
34 checks passed
@baronfel
baronfel deleted the baronfel-cross-arch-nativeaot-legs branch July 14, 2026 17:08
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview7 milestone Jul 15, 2026
baronfel added a commit that referenced this pull request Jul 15, 2026
The win-x64 -> win-arm64 NativeAOT cross-build AoT leg (added in #55205) has
been persistently failing in CI. Disable it via disableJob: true in both
.vsts-pr.yml and .vsts-ci.yml, with a comment linking the tracking issue
#55298 for dotnet/illink (ILCompiler) team follow-up.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b7c0dc09-64f3-40b8-9c5f-45b0fce2e461
dsplaisted added a commit to dsplaisted/sdk that referenced this pull request Jul 15, 2026
…um 843419)

The 'AoT: windows (arm64)' cross-build leg added in dotnet#55205 has never passed: the win-arm64 NativeAOT cross-link fails with 'LNK1322: cannot avoid potential ARM hazard (Cortex-A53 MPCore processor bug #843419)' because the ILCompiler-produced object is not split into per-function sections, so the MSVC arm64 linker cannot apply the erratum fixup. Only win-arm64 is affected (win-x64, osx-arm64, linux-x64/arm64 AoT legs all pass).

Set disableJob: true on the win-arm64 AoT job parameter set in .vsts-pr.yml and .vsts-ci.yml to stop it red-walling every build until the underlying ILCompiler fix lands. Re-enable by removing disableJob.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 59570d89-a7e3-4993-baa9-3fb1f442a617
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-dotnet AOT Items that are part of the dotnet CLI AOT-ification effort Area-Infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants