diff --git a/Documentation/docs-mobile/messages/xa1044.md b/Documentation/docs-mobile/messages/xa1044.md
new file mode 100644
index 00000000000..331dd99594c
--- /dev/null
+++ b/Documentation/docs-mobile/messages/xa1044.md
@@ -0,0 +1,45 @@
+---
+title: .NET for Android warning XA1044
+description: XA1044 warning code
+ms.date: 04/02/2026
+f1_keywords:
+ - "XA1044"
+---
+
+# .NET for Android warning XA1044
+
+## Example messages
+
+```
+warning XA1044: The MSBuild property 'RunAOTCompilation' is not compatible with the CoreCLR runtime and will be ignored. Either remove the property or guard it with a condition: Condition="'$(UseMonoRuntime)' == 'true'"
+```
+
+## Issue
+
+This warning indicates that a Mono-specific MSBuild property is set in
+the project file, but the project is configured to use a non-Mono
+runtime (such as CoreCLR or NativeAOT). The property will have no
+effect with the current runtime and will be ignored.
+
+Properties that trigger this warning include:
+- `RunAOTCompilation` — Mono AOT compilation; CoreCLR uses `PublishReadyToRun` instead.
+- `EnableLLVM` — Enables LLVM for the Mono AOT compiler.
+
+## Solution
+
+Remove the Mono-specific property from your project file or
+`Directory.Build.props`, or guard it with a runtime condition:
+
+```xml
+
+ true
+
+```
+
+For CoreCLR, use `PublishReadyToRun` instead of `RunAOTCompilation`:
+
+```xml
+
+ true
+
+```
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Aot.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Aot.targets
index d80be84d01c..3537c75fb4b 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Aot.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Aot.targets
@@ -21,7 +21,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
when $(MonoAOTCompilerTasksAssemblyPath) is blank:
https://github.com/dotnet/runtime/blob/69711860262e44458bbe276393ea3eb9f7a2192a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in#L20-L25
-->
-
+
@@ -39,7 +39,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
index e9c75e1667d..22816880d1b 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
@@ -119,6 +119,11 @@
true
true
false
+
+ <_AndroidXA1044_RunAOTCompilation Condition=" '$(RunAOTCompilation)' == 'true' and '$(_AndroidRuntime)' != 'MonoVM' ">true
+ <_AndroidXA1044_EnableLLVM Condition=" '$(EnableLLVM)' == 'true' and '$(_AndroidRuntime)' != 'MonoVM' ">true
+ false
+ false
<_AndroidXA1029 Condition=" '$(AotAssemblies)' != '' ">true
<_AndroidXA1030 Condition=" '$(RunAOTCompilation)' == 'true' and '$(PublishTrimmed)' == 'false' ">true
$(RunAOTCompilation)
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
index a1c98adf779..03e8aa2ea48 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
@@ -956,6 +956,15 @@ public static string XA1043 {
}
}
+ ///
+ /// Looks up a localized string similar to The MSBuild property '{0}' is not compatible with the {1} runtime and will be ignored. Either remove the property or guard it with a condition: Condition="'$(UseMonoRuntime)' == 'true'".
+ ///
+ public static string XA1044 {
+ get {
+ return ResourceManager.GetString("XA1044", 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 ca75ec196de..bdfc38d26bc 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
@@ -1007,6 +1007,13 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
The following are literal names and should not be translated: .NET.
{0} - The MSBuild property that has the incorrect value.
{1} - The current value of the property
+
+
+
+ The MSBuild property '{0}' is not compatible with the {1} runtime and will be ignored. Either remove the property or guard it with a condition: Condition="'$(UseMonoRuntime)' == 'true'"
+ The following are literal names and should not be translated: MSBuild, UseMonoRuntime.
+{0} - The MSBuild property name (e.g. RunAOTCompilation, EnableLLVM).
+{1} - The name of the .NET runtime (e.g. CoreCLR, NativeAOT).
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs
index d150196d51c..c98c394daed 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs
@@ -26,6 +26,12 @@ public void InstallAndroidDependenciesTest ([Values ("GoogleV2", "Xamarin")] str
return;
}
+ // The GoogleV2 manifest from Google doesn't have an ndk-bundle component,
+ // so the NDK dependency can't be resolved for runtimes that require it.
+ if (manifestType == "GoogleV2" && runtime == AndroidRuntime.NativeAOT) {
+ Assert.Ignore ("GoogleV2 manifest does not have an ndk-bundle component for NativeAOT");
+ }
+
// Set to true when we are marking a new Android API level as stable, but it has not
// been added to the Xamarin manifest yet.
var xamarin_manifest_needs_updating = false;
@@ -166,6 +172,11 @@ public void GetDependencyNdkRequiredConditions (string property, bool ndkRequire
Assert.Ignore ("NativeAOT doesn't support profiled AOT");
}
+ // NativeAOT always requires the NDK (PublishAot=true), so ndkRequired=false cases don't apply
+ if (runtime == AndroidRuntime.NativeAOT && !ndkRequired) {
+ Assert.Ignore ("NativeAOT always requires NDK via PublishAot=true");
+ }
+
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
};
@@ -188,6 +199,26 @@ public void GetDependencyNdkRequiredConditions (string property, bool ndkRequire
}
}
+ [Test]
+ public void NativeAotRequiresNdk ()
+ {
+ var proj = new XamarinAndroidApplicationProject {
+ IsRelease = true,
+ };
+ proj.SetRuntime (AndroidRuntime.NativeAOT);
+ using (var builder = CreateApkBuilder ()) {
+ builder.Verbosity = LoggerVerbosity.Detailed;
+ builder.Target = "GetAndroidDependencies";
+ Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
+ IEnumerable taskOutput = builder.LastBuildOutput
+ .Select (x => x.Trim ())
+ .SkipWhile (x => !x.StartsWith ("Task \"CalculateProjectDependencies\"", StringComparison.Ordinal))
+ .SkipWhile (x => !x.StartsWith ("Output Item(s):", StringComparison.Ordinal))
+ .TakeWhile (x => !x.StartsWith ("Done executing task \"CalculateProjectDependencies\"", StringComparison.Ordinal));
+ StringAssertEx.Contains ("ndk-bundle", taskOutput, "ndk-bundle should be a dependency for NativeAOT.");
+ }
+ }
+
[Test]
public void GetDependencyWhenBuildToolsAreMissingTest ([Values] AndroidRuntime runtime)
{
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs
index 6a6b91aa900..90f43cf6614 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs
@@ -492,5 +492,37 @@ public void CheckWhetherLibcAndLibmAreReferencedInAOTLibraries ()
}
}
+ [Test]
+ public void RunAOTCompilationWithCoreClrWarnsAndSkipsMonoAot ()
+ {
+ var proj = new XamarinAndroidApplicationProject {
+ IsRelease = true,
+ };
+ proj.SetRuntime (AndroidRuntime.CoreCLR);
+ proj.SetProperty ("RunAOTCompilation", "true");
+
+ using var b = CreateApkBuilder ();
+ Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
+ StringAssertEx.Contains ("warning XA1044", b.LastBuildOutput, "Build output should contain warning XA1044");
+ StringAssertEx.Contains ("RunAOTCompilation", b.LastBuildOutput, "Build output should mention RunAOTCompilation");
+ StringAssertEx.Contains ("CoreCLR", b.LastBuildOutput, "Build output should mention CoreCLR");
+ }
+
+ [Test]
+ public void EnableLLVMWithCoreClrWarnsAndIsIgnored ()
+ {
+ var proj = new XamarinAndroidApplicationProject {
+ IsRelease = true,
+ };
+ proj.SetRuntime (AndroidRuntime.CoreCLR);
+ proj.SetProperty ("EnableLLVM", "true");
+
+ using var b = CreateApkBuilder ();
+ Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
+ StringAssertEx.Contains ("warning XA1044", b.LastBuildOutput, "Build output should contain warning XA1044");
+ StringAssertEx.Contains ("EnableLLVM", b.LastBuildOutput, "Build output should mention EnableLLVM");
+ StringAssertEx.Contains ("CoreCLR", b.LastBuildOutput, "Build output should mention CoreCLR");
+ }
+
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 520e85fab23..8a18a922bb1 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -549,6 +549,16 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
ResourceName="XA1030"
Condition=" $(_AndroidXA1030) == 'true' "
/>
+
+
<_ProjectAndroidManifest>$(ProjectDir)$(AndroidManifest)
<_NdkRequired Condition="'$(EnableLLVM)' == 'True'">true
+ <_NdkRequired Condition="'$(PublishAot)' == 'true'">true
<_NdkRequired Condition="'$(_NdkRequired)' == ''">false