Skip to content

Fix XALNS7015: run FixAbstractMethodsStep before R2R in non-trimmed CoreCLR builds#11027

Draft
simonrozsival wants to merge 1 commit intomainfrom
fix/11025-r2r-abstract-methods
Draft

Fix XALNS7015: run FixAbstractMethodsStep before R2R in non-trimmed CoreCLR builds#11027
simonrozsival wants to merge 1 commit intomainfrom
fix/11025-r2r-abstract-methods

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

@simonrozsival simonrozsival commented Mar 26, 2026

Summary

Fixes #11025

In non-trimmed CoreCLR Release builds, PublishReadyToRun=true causes the inner build to compile IL assemblies to R2R images (via crossgen2) before _LinkAssembliesNoShrink runs. R2R assemblies have the ILONLY PE flag cleared, so when FixAbstractMethodsStep detects a missing abstract method and marks the assembly modified, SaveChangedAssemblyStep calls assembly.Write() via Mono.Cecil, which throws:

NotSupportedException: Writing mixed-mode assemblies is not supported

Changes

Fix: move _LinkAssembliesNoShrink to run before R2R compilation in the inner build

The previous _LinkAssembliesNoShrink target ran in the outer build using @(ResolvedAssemblies) and copied modified assemblies to an intermediate directory. This happened too late — the inner build had already produced R2R images by that point.

The fix restructures _LinkAssembliesNoShrink to run inside the inner build (BeforeTargets="_PrepareForReadyToRunCompilation"):

  • Xamarin.Android.Common.targets: Rewrite _LinkAssembliesNoShrink to run in the inner build when trimming is disabled. It operates on @(ResolvedFileToPublish) (available in the inner build) instead of @(ResolvedAssemblies) (outer build only). Assemblies are copied to an intermediate directory (linked-noshrink/) rather than modified in-place, since ResolvedFileToPublish items may point to shared locations (NuGet cache, runtime packs). After the task runs, ResolvedFileToPublish is updated so R2R and publish consume the modified copies. ABI metadata is computed via RuntimeIdentifierToAbi since _ResolveAndroidTooling does not run in the inner build.
  • Microsoft.Android.Sdk.AssemblyResolution.targets: In _PrepareAssemblies, populate _ResolvedAssemblies etc. unconditionally from @(ResolvedAssemblies) (no longer redirecting through the intermediate directory for non-trimmed builds).

Tests

  • Remove Assert.Ignore workarounds in BuildTest.SimilarAndroidXAssemblyNames and LinkerTests.AndroidAddKeepAlives for the CoreCLR Release non-trimmed case — these scenarios now pass.

Related

Copilot AI review requested due to automatic review settings March 26, 2026 16:08
@simonrozsival simonrozsival marked this pull request as draft March 26, 2026 16:10
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.

Pull request overview

Fixes the CoreCLR Release (non-trimmed) PublishReadyToRun=true build failure where FixAbstractMethodsStep tries to rewrite an already-R2R’d assembly and Mono.Cecil throws NotSupportedException for mixed-mode output.

Changes:

  • Run PostTrimmingPipeline before crossgen2/ReadyToRun for both trimmed and non-trimmed PublishReadyToRun builds, enabling FixAbstractMethods only in the non-trimmed path.
  • Update PostTrimmingPipeline to optionally include FixAbstractMethodsStep and mark processed assemblies as Android/user assemblies in StepContext.
  • Re-enable previously ignored CoreCLR test cases and add a unit regression test for FixAbstractMethods behavior via PostTrimmingPipeline.

Reviewed changes

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

File Description
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs Adds a regression unit test validating PostTrimmingPipeline can inject a missing abstract-method stub.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs Removes the CoreCLR non-trimmed ignore workaround now that the pipeline should run pre-R2R.
src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs Adds FixAbstractMethods support and updates StepContext flags so FixAbstractMethodsStep can run.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets Extends _PostTrimmingPipeline to also run for non-trimmed R2R builds and wires FixAbstractMethods into the task call.

@simonrozsival
Copy link
Copy Markdown
Member Author

Replying to the Copilot review comments — the implementation was reworked in commits 3-4, so all four comments are now outdated. Resolving them below.

…CoreCLR builds

In non-trimmed CoreCLR Release builds, PublishReadyToRun=true causes
the inner build to compile IL assemblies to R2R images (via crossgen2)
before _LinkAssembliesNoShrink runs. R2R assemblies have the ILONLY PE
flag cleared, so when FixAbstractMethodsStep detects a missing abstract
method and marks the assembly modified, SaveChangedAssemblyStep calls
assembly.Write() via Mono.Cecil, which throws:

  NotSupportedException: Writing mixed-mode assemblies is not supported

The fix restructures _LinkAssembliesNoShrink to run inside the inner
build (BeforeTargets=_PrepareForReadyToRunCompilation) so assembly
modifications happen before R2R compilation:

- Xamarin.Android.Common.targets: Rewrite _LinkAssembliesNoShrink to
  run in the inner build. It copies assemblies to an intermediate
  directory (linked-noshrink/) instead of modifying in-place, since
  ResolvedFileToPublish items may point to shared locations (NuGet
  cache, runtime packs). After the task runs, ResolvedFileToPublish
  is updated to point to the intermediate copies. Abi metadata is
  computed via RuntimeIdentifierToAbi since _ResolveAndroidTooling
  doesn't run in the inner build.

- Microsoft.Android.Sdk.AssemblyResolution.targets: In
  _PrepareAssemblies, populate _ResolvedAssemblies unconditionally
  from @(ResolvedAssemblies) instead of redirecting through the
  intermediate directory for non-trimmed builds.

- Remove Assert.Ignore workarounds in BuildTest and LinkerTests for
  the CoreCLR Release non-trimmed case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival force-pushed the fix/11025-r2r-abstract-methods branch from 5e65810 to 6469db8 Compare March 31, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XALNS7015: Writing mixed-mode assemblies is not supported when FixAbstractMethodsStep patches an R2R-compiled Java binding assembly (CoreCLR, .NET 11)

2 participants