[dotnet] Fix latent trimmable-static registrar bugs on non-NativeAOT runtimes - #26344
[dotnet] Fix latent trimmable-static registrar bugs on non-NativeAOT runtimes#26344rolfbjarne wants to merge 4 commits into
Conversation
…runtimes. Two fixes for building with an explicit 'Registrar=trimmable-static' on Mono/CoreCLR (these paths aren't hit by the NativeAOT default, but the registrar is a supported option on the other runtimes): - Only tell the trimmer to remove [ProtocolMember] attributes when the dynamic registrar has been removed (DynamicRegistrationSupported == false). The dynamic registrar reads these attributes via reflection at runtime, so trimming them while it's present errors out with IL2045. The option is moved into _SetDynamicRegistrationSupportedFeature so the computed _DynamicRegistrationSupported value is available (it isn't yet in _ComputeLinkerInputs). NativeAOT is unaffected (DynamicRegistrationSupported is always false there, so the attributes are still trimmed). - Fall back to the file name in _StripAssemblyIL when a ResolvedFileToPublish item has no OriginalRelativePath (e.g. the generated TypeMap assemblies). Otherwise the strip OutputPath collapsed to the bare stripped directory and ILStrip failed with 'Access to the path .../stripped/ is denied'. Also updates the SelectRegistrar comment to note NativeAOT defaults to trimmable-static on .NET 11+ (set earlier, in Xamarin.Shared.Sdk.props).
The condition referenced %(ResolvedFileToPublish.OriginalRelativePath) while modifying @(_AssembliesToBeStripped), which makes MSBuild batch over ResolvedFileToPublish instead of the items being modified: a single publish item without OriginalRelativePath would have applied the fallback OutputPath to every assembly, throwing away the valid relative paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6aeeddfd-3bd8-4129-ad90-7292860c4b66
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
This PR updates the .NET SDK MSBuild targets to fix a couple of issues in the trimmable-static registrar pipeline, particularly around when it’s safe to trim [ProtocolMember] attributes and a publish-time IL stripping failure caused by missing OriginalRelativePath metadata.
Changes:
- Gate
ObjCRuntime.TrimProtocolMemberAttributesonDynamicRegistrationSupported == false(computed from assembly-preparer output) to avoid trimming attributes needed by the dynamic registrar at runtime. - Move the
TrimProtocolMemberAttributesfeature switch configuration to the point where_DynamicRegistrationSupportedis known (inside_SetDynamicRegistrationSupportedFeature). - Fix
_StripAssemblyILoutput path computation whenResolvedFileToPublish.OriginalRelativePathis missing by falling back to%(Filename)%(Extension).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
… removed. The trimmable-static registrar only tells the trimmer to remove the [ProtocolMember] attributes (which reference generic types like NSSet<T> in optional protocol members) when the dynamic registrar has been removed - it reads these attributes via reflection at runtime, so they're kept when it's present. When the attributes aren't trimmed, NSSet<T> stays too, so the LinkedAwayGenericTypeAsOptionalMemberInProtocol test has nothing to verify. Ignore the test in that case (e.g. the prepare-assemblies|coreclr|trimmable- static-registrar variation on macOS, where DynamicRegistrationSupported is true), instead of failing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atic-latent-fixes
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
🔥 [CI Build #02407bd] Test results 🔥Test results❌ Tests failed on VSTS: test results 0 tests crashed, 6 tests failed, 197 tests passed. Failures❌ monotouch tests (iOS)4 tests failed, 15 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (macOS)2 tests failed, 17 tests passed.Failed tests
Html Report (VSDrops) Download Successes✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
Two latent bugs that only show up when the trimmable-static registrar is used on a runtime other than NativeAOT (they were found while measuring app size with
Registrar=trimmable-staticon CoreCLR and Mono).1.
ObjCRuntime.TrimProtocolMemberAttributeswas set too early, and unconditionallyThe feature switch that lets the trimmer remove
[ProtocolMember]attributes was set in_ComputeLinkerInputs, gated only onRegistrar == trimmable-static And PrepareAssemblies == true.The dynamic registrar reads those attributes reflectively at runtime, so when the dynamic registrar is still present the trimmer errors out with IL2045. Whether the dynamic registrar is present is only known after
_SetDynamicRegistrationSupportedFeaturehas run, so the item is moved into that target and gated on_DynamicRegistrationSupported == falseinstead.2.
ILStripfailed on the generated TypeMap assembliesSome
ResolvedFileToPublishitems don't haveOriginalRelativePathmetadata — the TypeMap assemblies the trimmable-static registrar generates are one such case. TheOutputPathexpression then collapsed to the bare stripped directory, andILStripfailed withAccess to the path '.../stripped/' is denied. Fall back to the file name whenOriginalRelativePathis empty.The second commit fixes the batching of that fallback: the condition referenced
%(ResolvedFileToPublish.OriginalRelativePath)while modifying@(_AssembliesToBeStripped), which makes MSBuild batch over the wrong item type — a single publish item withoutOriginalRelativePathwould have applied the fallbackOutputPathto every assembly.Notes
SelectRegistrarmentions a .NET 11 NativeAOTtrimmable-staticdefault that is introduced by a separate PR ([dotnet] Default to the trimmable-static registrar for NativeAOT on .NET 11 #26346); the first commit was kept verbatim as it was validated on thenet11.0branch.trimmable-staticisn't the default for any runtime today.🤖 Pull request created by Copilot