From 01308ec7139183e88287f54283082a454b355c81 Mon Sep 17 00:00:00 2001 From: Milos Kotlar <223556219+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 16:07:21 +0200 Subject: [PATCH 1/4] [net11.0] R2R-compile only System.Private.CoreLib for Debug CoreCLR mobile builds In Debug builds with CoreCLR on iOS, narrow _NonUserAssemblies to System.Private.CoreLib so that crossgen2 only ReadyToRun-compiles CoreLib and every other framework, MAUI, and NuGet assembly is excluded from R2R via the existing PublishReadyToRunExclude path. Non-R2R'd methods fall back to the CoreCLR interpreter at runtime (JIT is forbidden on iOS), which is the desired inner-loop behavior. Measured on SampleMAUI publish for ios-arm64 Debug: framework dylib drops from 318 MB to 28 MB and the .app bundle shrinks from 395 MB to 132 MB, with a corresponding reduction in crossgen2 time during build. Startup is unchanged in practice because the hot path through CoreLib is still R2R'd; only first-call cost for non-CoreLib methods shifts onto the interpreter, which is negligible for the inner-loop scenarios this default targets. Release builds are unaffected (FilterReadyToRunAssemblies already gates _SelectR2RAssemblies off for Release). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/targets/Microsoft.Sdk.R2R.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/targets/Microsoft.Sdk.R2R.targets b/dotnet/targets/Microsoft.Sdk.R2R.targets index 5db954f9fd45..bc35624ded12 100644 --- a/dotnet/targets/Microsoft.Sdk.R2R.targets +++ b/dotnet/targets/Microsoft.Sdk.R2R.targets @@ -125,7 +125,7 @@ <_ResolvedAssembliesToPublish Include="@(ResolvedFileToPublish)" Condition="'%(Extension)' == '.dll' And '%(ResolvedFileToPublish.Culture)' == '' And '%(ResolvedFileToPublish.DestinationSubDirectory)' == ''" /> <_NonUserAssemblies Include="@(_ResolvedAssembliesToPublish)" - Condition="'%(_ResolvedAssembliesToPublish.NuGetPackageId)' != ''" /> + Condition="'%(_ResolvedAssembliesToPublish.NuGetPackageId)' != '' And '%(Filename)' == 'System.Private.CoreLib'" /> <_UserAssemblies Include="@(_ResolvedAssembliesToPublish)" Exclude="@(_NonUserAssemblies)" /> From f3d55adef95011b5c2d56790aa9fa2440cdfd34e Mon Sep 17 00:00:00 2001 From: Milos Kotlar <223556219+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 16:19:20 +0200 Subject: [PATCH 2/4] Update _SelectR2RAssemblies comment to reflect new filter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/targets/Microsoft.Sdk.R2R.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/targets/Microsoft.Sdk.R2R.targets b/dotnet/targets/Microsoft.Sdk.R2R.targets index bc35624ded12..0ea9c5ed1fca 100644 --- a/dotnet/targets/Microsoft.Sdk.R2R.targets +++ b/dotnet/targets/Microsoft.Sdk.R2R.targets @@ -115,8 +115,8 @@ Date: Wed, 3 Jun 2026 16:04:01 +0200 Subject: [PATCH 3/4] [net11.0] Pass excluded framework assemblies as references to the CoreLib-only R2R composite Restricting the R2R composite to only System.Private.CoreLib makes the SDK flag every other framework assembly as hidden from the composite and drop it from the crossgen2 -r list. The composite is then built with zero references, producing a native image CoreCLR rejects at startup (FailFast in NativeImage::Open). Add a target that re-injects the excluded assemblies into _ReadyToRunCompositeBuildReferences (excluding the composite inputs), so crossgen2 receives them via -r while they still run as plain IL. Gated to filtered composite builds, so non-filtered builds are unaffected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/targets/Microsoft.Sdk.R2R.targets | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dotnet/targets/Microsoft.Sdk.R2R.targets b/dotnet/targets/Microsoft.Sdk.R2R.targets index 0ea9c5ed1fca..22e92a83d883 100644 --- a/dotnet/targets/Microsoft.Sdk.R2R.targets +++ b/dotnet/targets/Microsoft.Sdk.R2R.targets @@ -152,6 +152,17 @@ + + + <_ReadyToRunCompositeBuildReferences + Include="@(_ReadyToRunAssembliesToReference)" + Exclude="@(_ReadyToRunCompositeBuildInput);@(_ReadyToRunCompositeUnrootedBuildInput)" /> + + + Date: Thu, 4 Jun 2026 12:04:31 +0200 Subject: [PATCH 4/4] Use PublishReadyToRunCompositeRoots for BCL assemblies --- dotnet/targets/Microsoft.Sdk.R2R.targets | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/dotnet/targets/Microsoft.Sdk.R2R.targets b/dotnet/targets/Microsoft.Sdk.R2R.targets index 22e92a83d883..3e6b49ad294f 100644 --- a/dotnet/targets/Microsoft.Sdk.R2R.targets +++ b/dotnet/targets/Microsoft.Sdk.R2R.targets @@ -115,8 +115,8 @@ <_NonUserAssemblies Include="@(_ResolvedAssembliesToPublish)" - Condition="'%(_ResolvedAssembliesToPublish.NuGetPackageId)' != '' And '%(Filename)' == 'System.Private.CoreLib'" /> + Condition="'%(_ResolvedAssembliesToPublish.NuGetPackageId)' != ''" /> <_UserAssemblies Include="@(_ResolvedAssembliesToPublish)" Exclude="@(_NonUserAssemblies)" /> + @@ -152,14 +153,11 @@ - + - <_ReadyToRunCompositeBuildReferences - Include="@(_ReadyToRunAssembliesToReference)" - Exclude="@(_ReadyToRunCompositeBuildInput);@(_ReadyToRunCompositeUnrootedBuildInput)" /> +