Repository navigation
Enable AOT-compiled SDK tools in source-build - #7300
Merged
mthalman merged 3 commits intoJun 30, 2026
Merged
Conversation
The SDK bundles three ASP.NET Core CLI tools (dotnet-dev-certs, dotnet-user-jwts,
dotnet-user-secrets) as a Native AOT aggregate, but AOT publishing of these tools
only worked in the Microsoft build. In source-build it failed in two ways: restore
could not find a portable-RID runtime pack (NU1102), and once scoped to the build's
non-portable RID the previous SDK rejected the project with NETSDK1203 ("Ahead-of-time
compilation is not supported for the target runtime identifier"). The root cause is
that every repo in the VMR builds against a previous SDK; in a stage 1 source-build
leg that SDK is the Microsoft portable SDK, whose bundled props do not list the build's
non-portable RID (e.g. centos.10-x64) in the ILCompiler/runtime-pack RID sets and whose
packs/ folder has no NativeAOT pack for that RID.
Teach the previous SDK about the source-built non-portable RID and unblock AOT publishing,
then ship the resulting aggregate in source-build. Fixes dotnet/source-build#5567.
Arcade SDK:
- TargetingPacks.BeforeCommonTargets.targets: in source-build, append the build's
non-portable RID to the in-memory KnownILCompilerPack ILCompilerRuntimeIdentifiers
(new), alongside the existing KnownRuntimePack and KnownCrossgen2Pack RID sets. Switch
the appended value from $(NETCoreSdkRuntimeIdentifier) to $(TargetRid): in a stage 1 leg
the bootstrap SDK is portable, so $(NETCoreSdkRuntimeIdentifier) is the portable RID and
would not unblock publishing for the build's non-portable target RID.
- ProjectDefaults.targets: for source-build projects that publish with Native AOT, set
StripSymbols=false so the produced binary keeps embedded DWARF (no separate symbol file
or .gnu_debuglink). This is the AOT analog of source-build's KeepNativeSymbols=true and
satisfies the source-build native-symbol validation. Scoped to PublishAot so non-AOT
builds are unaffected, and gated on DotNetBuildSourceOnly so Microsoft builds still strip.
Placed in .targets (imported after the project sets PublishAot) so the condition is known.
runtime:
- Microsoft.DotNet.ILCompiler.SingleEntry.targets: when source-build publishes for the
non-portable target RID against a portable bootstrap SDK, the target OS derived from the
RID (e.g. "centos") is not a valid ILC target OS. Map it to the portable base OS (e.g.
"linux"), mirroring the existing non-portable SDK RID handling, without changing the
host/target pack names the SDK already resolved.
aspnetcore:
- Remove the DotNetBuildSourceOnly != 'true' gates that disabled PublishAot for the three
leaf tool projects and the aspnetcoretools aggregate, and include the aggregate in the
source-build project set (eng/Build.props). Simplify the aggregate's RuntimeIdentifier(s)
selection now that AOT runs in source-build too.
sdk:
- BundledDotnetTools.targets: bundle the Native AOT aspnetcoretools aggregate in source-build
instead of the per-tool managed IL packages. Remove the three source-build-only per-tool
entries and un-gate the RID-specific tool selection so the aggregate's non-portable RID
package (e.g. aspnetcoretools.centos.10-x64) is selected.
Co-authored-by: Copilot <[email protected]>
Contributor
There was a problem hiding this comment.
Pull request overview
Enables publishing and bundling the NativeAOT-compiled ASP.NET Core SDK CLI tools (via the aspnetcoretools aggregate) in VMR source-build legs by teaching the “previous SDK” about the build’s non-portable RID and adjusting NativeAOT/ILCompiler integration for that environment.
Changes:
- Always bundle
aspnetcoretools(including in source-build) and remove source-only fallback to individual RID-specific tool packages. - Enable NativeAOT publishing for
aspnetcoretoolsand its component tools during source-build, and include the aggregate in aspnetcore’s build graph. - In source-build, extend the previous SDK’s known pack RID sets to include
$(TargetRid)(including ILCompiler packs) and disable symbol stripping for PublishAot projects to satisfy source-build symbol validation.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/sdk/src/Layout/redist/targets/BundledDotnetTools.targets | Bundle aspnetcoretools in source-build and allow RID-specific package selection there. |
| src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets | Map non-portable source-build target OS to a portable OS token for ILC target OS derivation. |
| src/aspnetcore/src/Tools/NativeAot/aspnetcoretools/aspnetcoretools.csproj | Include in source-build and always enable PublishAot for the aggregate tool. |
| src/aspnetcore/src/Tools/dotnet-user-secrets/src/dotnet-user-secrets.csproj | Enable PublishAot for source-build (remove gating). |
| src/aspnetcore/src/Tools/dotnet-user-jwts/src/dotnet-user-jwts.csproj | Enable PublishAot for source-build (remove gating). |
| src/aspnetcore/src/Tools/dotnet-dev-certs/src/dotnet-dev-certs.csproj | Enable PublishAot for source-build (remove gating). |
| src/aspnetcore/eng/Build.props | Build the NativeAOT aggregate tool project during source-build. |
| src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/TargetingPacks.BeforeCommonTargets.targets | Append $(TargetRid) to Known* pack RID lists in source-build, including ILCompiler packs. |
| src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.targets | Disable NativeAOT symbol stripping in source-build to keep embedded DWARF in ELF outputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Member
Author
|
Code reviewers - PTAL |
akoeplinger
reviewed
Jun 25, 2026
Member
|
LGTM apart from one comment |
Addresses review feedback: the previous fix placed VMR-specific properties (DotNetBuildSourceOnly/TargetRid) in Microsoft.DotNet.ILCompiler.SingleEntry.targets, which ships in the ILCompiler NuGet package and runs on end-user builds. Replace that with a general ILC robustness fix using only ILC-intrinsic signals: when the target OS token derived from the RuntimeIdentifier is version-qualified (contains '.', e.g. 'centos.10' from 'centos.10-x64') and the RID is not the running SDK's own non-portable RID, map it to the SDK-reported portable base OS (e.g. 'linux'). Valid base OS tokens never contain a '.', so this reliably identifies a non-portable target RID published against a portable SDK. The SDK still resolves the host/target packs by full RID; only the ILC target OS needs normalizing. Co-authored-by: Copilot <[email protected]>
akoeplinger
approved these changes
Jun 27, 2026
am11
reviewed
Jun 27, 2026
jkotas
reviewed
Jun 27, 2026
jkotas
reviewed
Jun 27, 2026
jkotas
reviewed
Jun 27, 2026
jkotas
reviewed
Jun 27, 2026
Address PR review feedback on the Native AOT StripSymbols override in ProjectDefaults.targets: - Derive StripSymbols from the KeepNativeSymbols property instead of re-deriving the source-build policy from DotNetBuildSourceOnly, so a single overridable property controls native-symbol stripping. - Default KeepNativeSymbols to true for source-build here so it is in scope for repos (e.g. aspnetcore) that publish AOT SDK tools; it is otherwise only defaulted within the runtime build. - Drop the PublishAot scoping; StripSymbols is inert for non-AOT projects, so setting it unconditionally is harmless. - Correct the comment: shipping native binaries have their symbols stripped and archived by the distro packaging process, not shipped with embedded symbols; remove the issue link. Co-authored-by: Copilot <[email protected]>
jkotas
approved these changes
Jun 29, 2026
This was referenced Jul 1, 2026
This was referenced Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The SDK bundles three ASP.NET Core CLI tools (dotnet-dev-certs, dotnet-user-jwts, dotnet-user-secrets) as a Native AOT aggregate, but AOT publishing of these tools only worked in the Microsoft build. In source-build it failed in two ways: restore could not find a portable-RID runtime pack (
NU1102), and once scoped to the build's non-portable RID the previous SDK rejected the project withNETSDK1203("Ahead-of-time compilation is not supported for the target runtime identifier"). The root cause is that every repo in the VMR builds against a previous SDK; in a stage 1 source-build leg that SDK is the Microsoft portable SDK, whose bundled props do not list the build's non-portable RID (e.g.centos.10-x64) in the ILCompiler/runtime-pack RID sets and whose packs/ folder has no NativeAOT pack for that RID.Teach the previous SDK about the source-built non-portable RID and unblock AOT publishing, then ship the resulting aggregate in source-build. Fixes dotnet/source-build#5567.
Also dependent on #7297