From 739aca1ffb20dbd1eb9cbbc4eafdebc6ed6bbf0a Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 19 Aug 2026 09:59:39 -0500 Subject: [PATCH 1/4] [tests] Reproduce CoreCLR R2R assembly rewrite failure Add an enabled build test for the non-trimmed Release CoreCLR scenario where FixAbstractMethodsStep attempts to rewrite an R2R assembly and fails with XALNS7015. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 313238e1-f0ef-4218-b4ae-a124671f7881 --- .../Xamarin.Android.Build.Tests/BuildTest.cs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 63a575f42a2..b509e92ceee 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -2302,25 +2302,9 @@ public void CheckLintResourceFileReferencesAreFixed ([Values (AndroidRuntime.Cor [Test] [TestCase (true, AndroidRuntime.CoreCLR)] - [TestCase (false, AndroidRuntime.CoreCLR)] // TODO: [TestCase (false, AndroidRuntime.NativeAOT)] public void SimilarAndroidXAssemblyNames (bool publishTrimmed, AndroidRuntime runtime) { - if (!publishTrimmed && runtime == AndroidRuntime.CoreCLR) { - // This currently fails with the following exception: - // - // error XALNS7015: System.NotSupportedException: Writing mixed-mode assemblies is not supported - // at Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters) - // at Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters) - // at Mono.Cecil.ModuleDefinition.Write(String fileName, WriterParameters parameters) - // at Mono.Cecil.AssemblyDefinition.Write(String fileName, WriterParameters parameters) - // at Xamarin.Android.Tasks.SaveChangedAssemblyStep.ProcessAssembly(AssemblyDefinition assembly, StepContext context) in src/Xamarin.Android.Build.Tasks/Tasks/AssemblyModifierPipeline.cs:line 197 - // at Xamarin.Android.Tasks.AssemblyPipeline.Run(AssemblyDefinition assembly, StepContext context) in src/Xamarin.Android.Build.Tasks/Utilities/AssemblyPipeline.cs:line 26 - // at Xamarin.Android.Tasks.AssemblyModifierPipeline.RunPipeline(AssemblyPipeline pipeline, ITaskItem source, ITaskItem destination) in src/Xamarin.Android.Build.Tasks/Tasks/AssemblyModifierPipeline.cs:line 175 - Assert.Ignore ("CoreCLR: fails because of a Mono.Cecil lack of support"); - return; - } - bool aotAssemblies = runtime == AndroidRuntime.MonoVM && publishTrimmed; var proj = new XamarinAndroidApplicationProject { IsRelease = true, @@ -2337,6 +2321,23 @@ public void SimilarAndroidXAssemblyNames (bool publishTrimmed, AndroidRuntime ru Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); } + [Test] + public void FixAbstractMethodsOnReadyToRunAssembly () + { + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + PackageReferences = { + new Package { Id = "Xamarin.AndroidX.CustomView", Version = "1.1.0.17" }, + new Package { Id = "Xamarin.AndroidX.CustomView.PoolingContainer", Version = "1.0.0.4" }, + } + }; + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetProperty (KnownProperties.PublishTrimmed, false.ToString ()); + proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", "AndroidX.CustomView.PoolingContainer.PoolingContainer.IsPoolingContainer (null);"); + using var builder = CreateApkBuilder (); + Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); + } + [Test] public void IncrementalBuildDifferentDevice ([Values (AndroidRuntime.CoreCLR, AndroidRuntime.NativeAOT)] AndroidRuntime runtime) { From e305f870260c43056fd665af0182b634ccc3d475 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Thu, 20 Aug 2026 13:02:34 -0500 Subject: [PATCH 2/4] [build] Disable ReadyToRun without trimming Disable CoreCLR ReadyToRun and composite R2R when trimming is off, and emit XA0119 to explain how to enable it. This keeps non-trimmed assemblies as IL so LinkAssembliesNoShrink can safely rewrite them. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 313238e1-f0ef-4218-b4ae-a124671f7881 --- Documentation/docs-mobile/messages/xa0119.md | 2 +- .../targets/Microsoft.Android.Sdk.CoreCLR.targets | 3 +++ src/Xamarin.Android.Build.Tasks/Properties/Resources.resx | 4 ++++ .../Tests/Xamarin.Android.Build.Tests/BuildTest.cs | 1 + .../Xamarin.Android.Common.targets | 4 ++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/docs-mobile/messages/xa0119.md b/Documentation/docs-mobile/messages/xa0119.md index 17a00ac6594..5709cc48ea2 100644 --- a/Documentation/docs-mobile/messages/xa0119.md +++ b/Documentation/docs-mobile/messages/xa0119.md @@ -45,7 +45,7 @@ Remove the following from `Release` configurations: * `False` * `True` or in .NET 6 `True` -* `True` (for CoreCLR) +* `True` (for CoreCLR, when trimming is enabled) Consider submitting a [bug][bug] if you are getting one of these warnings under normal circumstances. diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets index ae749f1cf2c..9d687057a26 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.CoreCLR.targets @@ -17,6 +17,9 @@ This file contains the CoreCLR-specific MSBuild logic for .NET for Android. true + <_AndroidReadyToRunWithoutTrimming Condition=" '$(PublishReadyToRun)' == 'true' and '$(PublishTrimmed)' != 'true' ">true + false + false true <_IsPublishing Condition=" '$(_IsPublishing)' == '' and '$(PublishReadyToRun)' == 'true' ">true true diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx index ebf1bb55b0f..5b0e5b1999e 100644 --- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx +++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx @@ -317,6 +317,10 @@ The term "lock file" comes from NuGet. For example, search for "UnauthorizedLock Using fast deployment and ReadyToRun at the same time is not recommended. Use fast deployment for Debug configurations and ReadyToRun for Release configurations. The following are literal names and should not be translated: ReadyToRun, Debug, Release. + + ReadyToRun has been disabled because trimming is disabled. Set the 'PublishTrimmed' MSBuild property to 'true' to use ReadyToRun. + The following are literal names and should not be translated: ReadyToRun, 'PublishTrimmed', 'true'. + Assembly '{0}' is using '[assembly: {1}]', which is no longer supported. Use a newer version of this NuGet package or notify the library author. The following are literal names and should not be translated: [assembly: {1}], NuGet diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index b509e92ceee..5ea9020eef2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -2336,6 +2336,7 @@ public void FixAbstractMethodsOnReadyToRunAssembly () proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", "AndroidX.CustomView.PoolingContainer.PoolingContainer.IsPoolingContainer (null);"); using var builder = CreateApkBuilder (); Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); + StringAssertEx.Contains ("warning XA0119: ReadyToRun has been disabled because trimming is disabled.", builder.LastBuildOutput); } [Test] diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 57fa1a57afc..71fc58ccc8a 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -528,6 +528,10 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. ResourceName="XA0119_ReadyToRun" Condition=" '$(AndroidEnableFastDeployment)' == 'True' And '$(PublishReadyToRun)' == 'True' " /> + Date: Thu, 20 Aug 2026 14:21:18 -0500 Subject: [PATCH 3/4] [tests] Restore untrimmed CoreCLR AndroidX test Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 313238e1-f0ef-4218-b4ae-a124671f7881 --- .../Tests/Xamarin.Android.Build.Tests/BuildTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 5ea9020eef2..b0340332d29 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -2302,6 +2302,7 @@ public void CheckLintResourceFileReferencesAreFixed ([Values (AndroidRuntime.Cor [Test] [TestCase (true, AndroidRuntime.CoreCLR)] + [TestCase (false, AndroidRuntime.CoreCLR)] // TODO: [TestCase (false, AndroidRuntime.NativeAOT)] public void SimilarAndroidXAssemblyNames (bool publishTrimmed, AndroidRuntime runtime) { From 35a95c392ba26e33e632386033f9d79c58e764e1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Thu, 20 Aug 2026 14:27:56 -0500 Subject: [PATCH 4/4] [tests] Enable trimming in ReadyToRun publish test Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 313238e1-f0ef-4218-b4ae-a124671f7881 --- .../Tests/Xamarin.Android.Build.Tests/BuildTest2.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 48cd2eb9d58..0ceae4e9336 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -115,6 +115,7 @@ public void BasicApplicationPublishReadyToRunCustomConfiguration ([Values] bool proj.SetProperty ("AndroidEnableAssemblyCompression", "false"); proj.SetProperty ("Optimize", "true"); proj.SetProperty ("DebugType", "None"); + proj.SetProperty ("PublishTrimmed", "true"); proj.SetProperty ("PublishReadyToRunComposite", isComposite.ToString ()); // Use `dotnet publish` rather than `msbuild /t:Publish`: only the `dotnet publish` CLI