From 1d14aab42d614bdfa41dd9869d4eef0dc1a50afc Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Tue, 1 Sep 2026 06:30:28 +0200 Subject: [PATCH 1/2] [build] Error on marshal methods with ReadyToRun Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- Documentation/docs-mobile/TOC.yml | 2 + .../building-apps/build-properties.md | 3 ++ Documentation/docs-mobile/messages/index.md | 1 + Documentation/docs-mobile/messages/xa1049.md | 41 +++++++++++++++++++ .../Properties/Resources.Designer.cs | 9 ++++ .../Properties/Resources.resx | 4 ++ .../Xamarin.Android.Build.Tests/BuildTest2.cs | 18 ++++++++ .../Xamarin.Android.Common.targets | 4 ++ 8 files changed, 82 insertions(+) create mode 100644 Documentation/docs-mobile/messages/xa1049.md diff --git a/Documentation/docs-mobile/TOC.yml b/Documentation/docs-mobile/TOC.yml index 25edf535e06..1244c066b05 100644 --- a/Documentation/docs-mobile/TOC.yml +++ b/Documentation/docs-mobile/TOC.yml @@ -270,6 +270,8 @@ href: messages/xa1043.md - name: XA1048 href: messages/xa1048.md + - name: XA1049 + href: messages/xa1049.md - name: "XA2xxx: Linker" items: - name: "XA2xxx: Linker" diff --git a/Documentation/docs-mobile/building-apps/build-properties.md b/Documentation/docs-mobile/building-apps/build-properties.md index 11d6036471b..475a57bbbdd 100644 --- a/Documentation/docs-mobile/building-apps/build-properties.md +++ b/Documentation/docs-mobile/building-apps/build-properties.md @@ -399,6 +399,9 @@ for Java `native` method registration. This property is False by default. +This property cannot be set to `true` when +[`$(PublishReadyToRun)`](#publishreadytorun) is `true`. + Added in .NET 8. ## AndroidEnableMultiDex diff --git a/Documentation/docs-mobile/messages/index.md b/Documentation/docs-mobile/messages/index.md index 8c4ea0192de..dabb47571de 100644 --- a/Documentation/docs-mobile/messages/index.md +++ b/Documentation/docs-mobile/messages/index.md @@ -158,6 +158,7 @@ Either change the value in the AndroidManifest.xml to match the $(SupportedOSPla + [XA1046](xa1046.md): Attribute '{0}' in element '{1}' has value '{2}' that cannot be parsed as boolean; {3} line {4}. + [XA1047](xa1047.md): Required attribute '{0}' missing from element '{1}'; {2} line {3}. + [XA1048](xa1048.md): '{0}' does not contain an <instrumentation> element. ++ [XA1049](xa1049.md): The 'AndroidEnableMarshalMethods' and 'PublishReadyToRun' MSBuild properties cannot both be set to 'true'. ## XA2xxx: Linker diff --git a/Documentation/docs-mobile/messages/xa1049.md b/Documentation/docs-mobile/messages/xa1049.md new file mode 100644 index 00000000000..4d617f1abda --- /dev/null +++ b/Documentation/docs-mobile/messages/xa1049.md @@ -0,0 +1,41 @@ +--- +title: .NET for Android error XA1049 +description: XA1049 error code +ms.date: 08/31/2026 +f1_keywords: + - "XA1049" +--- + +# .NET for Android error XA1049 + +## Example messages + +```dotnetcli +error XA1049: The 'AndroidEnableMarshalMethods' and 'PublishReadyToRun' MSBuild properties cannot both be set to 'true'. Set one property to 'false'. +``` + +## Issue + +[`$(AndroidEnableMarshalMethods)`](../building-apps/build-properties.md#androidenablemarshalmethods) +rewrites managed assemblies after trimming, while +[`$(PublishReadyToRun)`](../building-apps/build-properties.md#publishreadytorun) +adds native code to those assemblies. The marshal methods rewriter cannot modify +ReadyToRun assemblies. + +## Solution + +Disable marshal methods or ReadyToRun in the project file: + +```xml + + false + +``` + +Alternatively: + +```xml + + false + +``` diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs index 15af76356e0..db2a9c4243c 100644 --- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs +++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs @@ -1015,6 +1015,15 @@ public static string XA1048 { return ResourceManager.GetString("XA1048", resourceCulture); } } + + /// + /// Looks up a localized string similar to The 'AndroidEnableMarshalMethods' and 'PublishReadyToRun' MSBuild properties cannot both be set to 'true'. Set one property to 'false'.. + /// + public static string XA1049 { + get { + return ResourceManager.GetString("XA1049", resourceCulture); + } + } /// /// Looks up a localized string similar to Use of AppDomain.CreateDomain() detected in assembly: {0}. .NET 6 and higher will only support a single AppDomain, so this API will no longer be available in .NET for Android once .NET 6 is released.. diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx index 75a82d67971..aef2dbc527a 100644 --- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx +++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx @@ -1128,6 +1128,10 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS {0} - The path to the AndroidManifest.xml file. + + The 'AndroidEnableMarshalMethods' and 'PublishReadyToRun' MSBuild properties cannot both be set to 'true'. Set one property to 'false'. + The following are literal names and should not be translated: AndroidEnableMarshalMethods, PublishReadyToRun, MSBuild, true, false. + Java dependency '{0}' is not satisfied. The following are literal names and should not be translated: Java. 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 b5c91792cf8..b3eb8e87727 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 @@ -101,6 +101,24 @@ public void BasicApplicationPublishReadyToRun ([Values] bool isComposite, [Value StringAssert.Contains ("@uncompressed_assemblies_data_buffer = dso_local local_unnamed_addr global [0 x i8] zeroinitializer, align 1", compressedAssembliesSourceText); } + [Test] + public void AndroidEnableMarshalMethodsWithReadyToRunFailsBuild () + { + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + EnableMarshalMethods = true, + }; + proj.SetRuntime (AndroidRuntime.CoreCLR); + proj.SetProperty ("PublishReadyToRun", "true"); + + using var b = CreateApkBuilder (); + b.ThrowOnBuildFailure = false; + Assert.IsFalse (b.Build (proj), "Build should have failed."); + StringAssertEx.Contains ("error XA1049", b.LastBuildOutput); + StringAssertEx.Contains ("AndroidEnableMarshalMethods", b.LastBuildOutput); + StringAssertEx.Contains ("PublishReadyToRun", b.LastBuildOutput); + } + [Test] public void BasicApplicationPublishReadyToRunCustomConfiguration ([Values] bool isComposite, [Values ("android-x64", "android-arm64")] string rid) { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 72b19c3ffec..c9c6506f3ba 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -532,6 +532,10 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. ResourceName="XA0119_ReadyToRunWithoutTrimming" Condition=" '$(_AndroidReadyToRunWithoutTrimming)' == 'true' " /> + Date: Tue, 1 Sep 2026 10:07:48 +0200 Subject: [PATCH 2/2] [build] Address marshal methods review Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Tests/Xamarin.Android.Build.Tests/BuildTest2.cs | 1 + src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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 b3eb8e87727..19d3f973235 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 @@ -117,6 +117,7 @@ public void AndroidEnableMarshalMethodsWithReadyToRunFailsBuild () StringAssertEx.Contains ("error XA1049", b.LastBuildOutput); StringAssertEx.Contains ("AndroidEnableMarshalMethods", b.LastBuildOutput); StringAssertEx.Contains ("PublishReadyToRun", b.LastBuildOutput); + StringAssertEx.DoesNotContain ("XARMM7015", b.LastBuildOutput, "Build should fail before rewriting ReadyToRun assemblies."); } [Test] diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index c9c6506f3ba..2c081594465 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -534,7 +534,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. />