Skip to content

[net11.0] Fully trim assemblies in R2R image when using SdkOnly link mode in Debug#24909

Closed
kotlarmilos wants to merge 2 commits intonet11.0from
dev/miloskotlar/r2r-all-assemblies
Closed

[net11.0] Fully trim assemblies in R2R image when using SdkOnly link mode in Debug#24909
kotlarmilos wants to merge 2 commits intonet11.0from
dev/miloskotlar/r2r-all-assemblies

Conversation

@kotlarmilos
Copy link
Copy Markdown
Member

When FilterReadyToRunAssemblies is active (Debug builds with CoreCLR R2R), only NuGet/framework assemblies enter the R2R composite image while user assemblies run interpreted for debugging.

Currently, with the default SdkOnly link mode, framework assemblies are only trimmed if they have IsTrimmable=true metadata. This leaves some assemblies untrimmed in the R2R image, increasing bundle size unnecessarily since these assemblies won't be used for debugging.

This change adds a _SetR2RAssemblyTrimMode target that, when _LinkMode == 'SdkOnly' and R2R filtering is active:

  • Forces TrimMode=link and IsTrimmable=true on all NuGet/framework assemblies (entering R2R image)
  • Forces TrimMode=copy on user assemblies (interpreted, kept intact for debugging)

If the user explicitly sets Full or None link mode, their choice is respected.

Results (MAUI template app, Debug, CoreCLR, iOS arm64):

Metric Before After Delta
Bundle Size 140.42 MB 112.66 MB -27.76 MB (-19.8%)
Total Startup 183.89 ms 172.25 ms -11.64 ms (-6.3%)

…mode

When FilterReadyToRunAssemblies is active (Debug builds with CoreCLR R2R),
only NuGet/framework assemblies enter the R2R composite image while user
assemblies run interpreted for debugging.

Currently, with the default SdkOnly link mode, framework assemblies are
only trimmed if they have IsTrimmable=true metadata. This leaves some
assemblies untrimmed in the R2R image, increasing bundle size.

Add _SetR2RAssemblyTrimMode target that forces TrimMode=link on all
NuGet/framework assemblies entering the R2R image and TrimMode=copy on
user assemblies when _LinkMode is SdkOnly.

Results (MAUI template, Debug, CoreCLR, iOS arm64):
- Bundle size: 140.42 MB -> 112.66 MB (-27.76 MB, -19.8%)
- Startup: 183.89 ms -> 172.25 ms (-11.64 ms, -6.3%)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kotlarmilos kotlarmilos changed the title [CoreCLR] Fully trim assemblies in R2R image when using SdkOnly link mode [net11.0] Fully trim assemblies in R2R image when using SdkOnly link mode in Debug Mar 17, 2026
@kotlarmilos kotlarmilos self-assigned this Mar 17, 2026
@kotlarmilos kotlarmilos added this to the .NET 11 milestone Mar 17, 2026
@kotlarmilos kotlarmilos added iOS Issues affecting iOS CoreCLR Bugs related to our CoreCLR support labels Mar 17, 2026
@kotlarmilos kotlarmilos marked this pull request as ready for review March 17, 2026 12:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [CI Build #b9a2ea1] Build passed (Build packages) ✅

Pipeline on Agent
Hash: b9a2ea1b45bc2c195afe682fce4a4bd547a358d0 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [PR Build #b9a2ea1] Build passed (Detect API changes) ✅

Pipeline on Agent
Hash: b9a2ea1b45bc2c195afe682fce4a4bd547a358d0 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [CI Build #b9a2ea1] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: b9a2ea1b45bc2c195afe682fce4a4bd547a358d0 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: b9a2ea1b45bc2c195afe682fce4a4bd547a358d0 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

🔥 [CI Build #b9a2ea1] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

0 tests crashed, 1 tests failed, 154 tests passed.

Failures

❌ Tests on macOS Tahoe (26) tests

1 tests failed, 4 tests passed.

Failed tests

  • monotouch-test: Failed

Html Report (VSDrops) Download

Successes

✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 9 tests passed. Html Report (VSDrops) Download
✅ linker: All 44 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 13 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 17 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 12 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 13 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: b9a2ea1b45bc2c195afe682fce4a4bd547a358d0 [PR build]

@rolfbjarne
Copy link
Copy Markdown
Member

Currently, with the default SdkOnly link mode, framework assemblies are only trimmed if they have IsTrimmable=true metadata. This leaves some assemblies untrimmed in the R2R image, increasing bundle size unnecessarily since these assemblies won't be used for debugging.

If a framework assembly doesn't have IsTrimmable=true, then presumably it's not trimmable - so I'm not sure we should override that.

If a framework assembly is indeed trimmable, then it seems like the better solution would be to set IsTrimmable=true for those assemblies.

@rolfbjarne
Copy link
Copy Markdown
Member

Also which assemblies are these?

@kotlarmilos
Copy link
Copy Markdown
Member Author

kotlarmilos commented Mar 18, 2026

The assemblies in the R2R image that don't have IsTrimmable=true are:

  • Microsoft.Maui.Controls.dll
  • Microsoft.Maui.dll
  • Microsoft.Maui.Graphics.dll
  • Microsoft.Maui.Controls.Xaml.dll
  • System.Private.CoreLib.dll

I initially misunderstood SdkOnly. I thought it only trimmed SDK/framework assemblies, not all assemblies with IsTrimmable=true. Since the default IsTrimmable=false, I assume that many third-party nuget packs don't have it explicitly set, but might be wrong.

If a framework assembly is indeed trimmable, then it seems like the better solution would be to set IsTrimmable=true for those assemblies.

What do you have in mind here?

@rolfbjarne
Copy link
Copy Markdown
Member

The assemblies in the R2R image that don't have IsTrimmable=true are:

  • Microsoft.Maui.Controls.dll
  • Microsoft.Maui.dll
  • Microsoft.Maui.Graphics.dll
  • Microsoft.Maui.Controls.Xaml.dll
  • System.Private.CoreLib.dll

Note that IsTrimmable can be set as an assembly attribute as well: https://github.com/dotnet/runtime/blob/main/docs/design/tools/illink/trimmed-assemblies.md#net-6

And looking at System.Private.CoreLib.dll, it has:

[assembly: System.Reflection.AssemblyMetadata ("IsTrimmable", "True")]

so it's strange to see SPC.dll in this list.

If a framework assembly is indeed trimmable, then it seems like the better solution would be to set IsTrimmable=true for those assemblies.

What do you have in mind here?

Set the same AssemblyMetadata attribute on the MAUI assemblies as well (if they're indeed trimmable).

This has a few additional advantages:

  • Apps behave the same between Debug and Release
  • Release also gets the same size gain

I initially misunderstood SdkOnly. I thought it only trimmed SDK/framework assemblies, not all assemblies with IsTrimmable=true. Since the default IsTrimmable=false, I assume that many third-party nuget packs don't have it explicitly set, but might be wrong.

That's a historical accident: "SdkOnly" is old, and before .NET that's exactly what it meant: trim the framework assemblies only. In .NET things are somewhat different (to start: what's a "framework assembly" exactly?), so we changed the meaning a little bit to be "all assemblies that declare themselves to be trimmable", which was both close enough to the truth (only BCL assemblies declared themselves to be trimmmable, at least at first), and it's also close in spirit (trim all assemblies that are known to trimmer safe).

@kotlarmilos
Copy link
Copy Markdown
Member Author

Thanks. Closing this PR in favour of dotnet/maui#34573

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CoreCLR Bugs related to our CoreCLR support iOS Issues affecting iOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants