From 9d8244d262d90d576376b227ae44210e594699f1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 27 Oct 2026 09:37:30 -0500 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Run define constants in-process Allow to run in the MSBuild process when multithreaded builds use -mt. The task builds an in-memory list of constants, so it does not need a separate task host. Use the existing multithreaded base and declare the task attribute directly. Keep constant generation unchanged and add focused tests for API levels, version sanitizing, and invalid input. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Tasks/GetAndroidDefineConstants.cs | 3 +- .../Tasks/GetAndroidDefineConstantsTests.cs | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetAndroidDefineConstantsTests.cs diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs index b0c99dd78cf..58925c4cc3e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs @@ -10,7 +10,8 @@ namespace Xamarin.Android.Tasks { - public class GetAndroidDefineConstants : AndroidTask + [MSBuildMultiThreadableTask] + public class GetAndroidDefineConstants : MultithreadedAndroidTask { public override string TaskPrefix => "GAD"; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetAndroidDefineConstantsTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetAndroidDefineConstantsTests.cs new file mode 100644 index 00000000000..bd7a35200fd --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GetAndroidDefineConstantsTests.cs @@ -0,0 +1,48 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Build.Framework; +using NUnit.Framework; +using Xamarin.Android.Tasks; + +namespace Xamarin.Android.Build.Tests +{ + [TestFixture] + public class GetAndroidDefineConstantsTests + { + [TestCase ("36", null, 36, "")] + [TestCase ("36.1", null, 36, "__ANDROID_36_1__")] + [TestCase ("38.2", "11.0-rc+test", 38, "__ANDROID_36_1__;__ANDROID_37_1__;__ANDROID_37_2__;__ANDROID_37_3__;__ANDROID_37_4__;__ANDROID_38_1__;__ANDROID_38_2__")] + public void Constants (string apiLevel, string? productVersion, int major, string minorConstants) + { + var task = new GetAndroidDefineConstants { + AndroidApiLevel = apiLevel, + ProductVersion = productVersion, + }; + Assert.IsTrue (task.Execute ()); + var constants = task.AndroidDefineConstants ?? throw new InvalidOperationException ("No constants returned."); + var expected = new List (); + if (productVersion != null) + expected.Add ("__XAMARIN_ANDROID_11_0_rc_test__"); + expected.AddRange (["__MOBILE__", "__ANDROID__"]); + expected.AddRange (Enumerable.Range (1, major).Select (i => $"__ANDROID_{i}__")); + expected.AddRange (minorConstants.Split (';', StringSplitOptions.RemoveEmptyEntries)); + CollectionAssert.AreEqual (expected, constants.Select (i => i.ItemSpec)); + } + + [TestCase ("")] + [TestCase ("invalid")] + public void InvalidApiLevel (string apiLevel) + { + var errors = new List (); + var task = new GetAndroidDefineConstants { + AndroidApiLevel = apiLevel, + BuildEngine = new MockBuildEngine (TestContext.Out, errors: errors), + }; + Assert.IsFalse (task.Execute ()); + Assert.IsNull (task.AndroidDefineConstants); + Assert.IsEmpty (errors); + } + } +}