Skip to content

[dotnet] Default PublishTrimmed=false when there's nothing for the trimmer to do.#25909

Open
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/assembly-preparer-speed-v2
Open

[dotnet] Default PublishTrimmed=false when there's nothing for the trimmer to do.#25909
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/assembly-preparer-speed-v2

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

Previously we always defaulted PublishTrimmed to true (except when building from Windows without a connection to a Mac), and disallowed setting it to false.

Now default PublishTrimmed to false when all of the following are true:

  • No assemblies are being trimmed (TrimMode is 'copy').
  • The link mode is 'None'.
  • Both PrepareAssemblies and PostProcessAssemblies are 'true'.

When both PrepareAssemblies and PostProcessAssemblies are true, all the custom trimmer steps are moved to the assembly-preparer's post-processing step instead of running inside the trimmer. Combined with a link mode of 'None' (nothing is trimmed), there's nothing left for the trimmer (ILLink) to do, so we can skip it entirely.

Skipping the trimmer meant the AOT dedup assembly (aot-instances.dll) was no longer created, because _CreateAOTDedupAssembly runs BeforeTargets=PrepareForILLink, and PrepareForILLink doesn't run when the trimmer is skipped. Fix this by making _AddDedupAssemblyToResolvedFileToPublish depend on _CreateAOTDedupAssembly, so the dedup assembly is created before the assemblies are post-processed regardless of whether the trimmer runs.

Perf numbers are kind of all over the place, probably due to randomness on my machine, but this should eventually speed up the build once the PrepareAssembly task is optimized.

Before:

Project Runtime identifier Link mode PrepareAssemblies=false PrepareAssemblies=true Difference
monotouch-test ios-arm64 None 00:02:05.46 00:02:09.64 00:00:04.18
monotouch-test iossimulator-arm64 None 00:01:34.26 00:01:38.97 00:00:04.70
MySimpleApp ios-arm64 None 00:01:20.30 00:01:23.26 00:00:02.96
MySimpleApp iossimulator-arm64 None 00:00:53.64 00:00:55.38 00:00:01.74

After:

Project Runtime identifier Link mode PrepareAssemblies=false PrepareAssemblies=true Difference
monotouch-test ios-arm64 None 00:02:06.53 00:02:12.52 00:00:05.99
monotouch-test iossimulator-arm64 None 00:01:36.81 00:01:36.34 00:00:00.46
MySimpleApp ios-arm64 None 00:01:14.63 00:01:19.11 00:00:04.48
MySimpleApp iossimulator-arm64 None 00:00:54.26 00:00:53.07 00:00:01.19

Also change the TimeSpan formatting in the performance report to print 2 fractional-second digits instead of 7. Even 2 is way too much precision, but it looks nicely symmetrical with the other double-digit numerical values.

…immer to do.

Previously we always defaulted PublishTrimmed to true (except when building from Windows without a connection to a Mac), and disallowed setting it to false.

Now default PublishTrimmed to false when all of the following are true:

* No assemblies are being trimmed (TrimMode is 'copy').
* The link mode is 'None'.
* Both PrepareAssemblies and PostProcessAssemblies are 'true'.

When both PrepareAssemblies and PostProcessAssemblies are true, all the custom trimmer steps are moved to the assembly-preparer's post-processing step instead of running inside the trimmer. Combined with a link mode of 'None' (nothing is trimmed), there's nothing left for the trimmer (ILLink) to do, so we can skip it entirely.

Skipping the trimmer meant the AOT dedup assembly (aot-instances.dll) was no longer created, because _CreateAOTDedupAssembly runs BeforeTargets=PrepareForILLink, and PrepareForILLink doesn't run when the trimmer is skipped. Fix this by making _AddDedupAssemblyToResolvedFileToPublish depend on _CreateAOTDedupAssembly, so the dedup assembly is created before the assemblies are post-processed regardless of whether the trimmer runs.

Perf numbers are kind of all over the place, probably due to randomness on my machine, but this should eventually speed up the build once the PrepareAssembly task is optimized.

Before:

| Project        | Runtime identifier | Link mode | PrepareAssemblies=false | PrepareAssemblies=true | Difference  |
| -------------- | ------------------ | --------- | ----------------------- | ---------------------- | ----------- |
| monotouch-test | ios-arm64          | None      | 00:02:05.46             | 00:02:09.64            | 00:00:04.18 |
| monotouch-test | iossimulator-arm64 | None      | 00:01:34.26             | 00:01:38.97            | 00:00:04.70 |
| MySimpleApp    | ios-arm64          | None      | 00:01:20.30             | 00:01:23.26            | 00:00:02.96 |
| MySimpleApp    | iossimulator-arm64 | None      | 00:00:53.64             | 00:00:55.38            | 00:00:01.74 |

After:

| Project        | Runtime identifier | Link mode | PrepareAssemblies=false | PrepareAssemblies=true | Difference  |
| -------------- | ------------------ | --------- | ----------------------- | ---------------------- | ----------- |
| monotouch-test | ios-arm64          | None      | 00:02:06.53             | 00:02:12.52            | 00:00:05.99 |
| monotouch-test | iossimulator-arm64 | None      | 00:01:36.81             | 00:01:36.34            | 00:00:00.46 |
| MySimpleApp    | ios-arm64          | None      | 00:01:14.63             | 00:01:19.11            | 00:00:04.48 |
| MySimpleApp    | iossimulator-arm64 | None      | 00:00:54.26             | 00:00:53.07            | 00:00:01.19 |

Also change the TimeSpan formatting in the performance report to print 2 fractional-second digits instead of 7. Even 2 is way too much precision, but it looks nicely symmetrical with the other double-digit numerical values.

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


Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 2, 2026 11:49

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

Updates the .NET-for-Apple MSBuild trimming pipeline to avoid invoking ILLink when it has no work to do (no trimming + trimmer custom steps moved to assembly-preparer), while ensuring the AOT dedup assembly still gets generated and adjusting perf-report formatting.

Changes:

  • Default PublishTrimmed=false when link mode is None, TrimMode=copy, and both PrepareAssemblies + PostProcessAssemblies are enabled (so ILLink can be skipped).
  • Ensure aot-instances.dll is created even when ILLink is skipped by making _AddDedupAssemblyToResolvedFileToPublish depend on _CreateAOTDedupAssembly.
  • Add a regression test for the new defaulting behavior and reduce TimeSpan precision in performance reports.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/dotnet/UnitTests/PublishTrimmedTest.cs Adds a unit test asserting PublishTrimmed defaults to false when the trimmer can be skipped.
tests/dotnet/UnitTests/PerformanceTests.cs Changes perf-report TimeSpan formatting to show fewer fractional-second digits.
dotnet/targets/Xamarin.Shared.Sdk.targets Implements the new PublishTrimmed defaulting logic and fixes dedup assembly generation ordering when ILLink is skipped.

assembly-preparer's post-processing step instead), then there's nothing for the trimmer to do, so
default PublishTrimmed to false to skip running the trimmer entirely.
-->
<_CanSkipTrimmer Condition="'$(_CanSkipTrimmer)' == '' And '$(_LinkMode)' == 'None' And '$(TrimMode)' == 'copy' And '$(PrepareAssemblies)' == 'true' And '$(PostProcessAssemblies)' == 'true'">true</_CanSkipTrimmer>
}
}

static string FormatTimeSpan (TimeSpan value) => value.ToString (@"hh\:mm\:ss\.ff");
@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

This comment has been minimized.

…king.

The test read the 'PublishTrimmed' property value from the binlog, but that
property is computed inside the '_ComputePublishTrimmed' target. Property
values assigned inside a target are only logged in the binlog when property
tracking is enabled (via the 'MsBuildLogPropertyTracking' environment
variable). This isn't the case on CI, so the test failed there while passing
locally for anyone who happens to have that environment variable set.

Assert that the trimmer ('ILLink' target) didn't execute instead, which is
the actual behavior being verified and is independent of property tracking.

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

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ [PR Build #1bb00c1] Build passed (Build packages) ✅

Pipeline on Agent
Hash: 1bb00c16e85886b4516730c621118edf0bd2e305 [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

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

Pipeline on Agent
Hash: 1bb00c16e85886b4516730c621118edf0bd2e305 [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ [PR Build #1bb00c1] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: 1bb00c16e85886b4516730c621118edf0bd2e305 [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: 1bb00c16e85886b4516730c621118edf0bd2e305 [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🔥 [CI Build #1bb00c1] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

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

Failures

❌ linker tests (iOS)

🔥 Failed catastrophically on VSTS: test results - linker_ios (no summary found).

Html Report (VSDrops) Download

Successes

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ 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 4 tests passed. Html Report (VSDrops) Download
✅ linker (MacCatalyst): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (macOS): All 21 tests passed. Html Report (VSDrops) Download
✅ linker (tvOS): All 15 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 17 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 18 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 Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ 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
✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: 1bb00c16e85886b4516730c621118edf0bd2e305 [PR build]

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants