diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets
index 411e06d32a9..eed1d4765df 100644
--- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets
+++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets
@@ -234,7 +234,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
CreatePackagePerAbi="$(AndroidCreatePackagePerAbi)"
AssetsDirectory="$(MonoAndroidAssetsDirIntermediate)"
AdditionalAndroidAssetPaths="@(LibraryAssetDirectories)"
- AndroidSdkPlatform="$(_AndroidApiLevel)"
+ AndroidApiLevel="$(_AndroidApiLevel)"
JavaDesignerOutputDirectory="$(AaptTemporaryDirectory)"
ManifestFiles="$(IntermediateOutputPath)android\AndroidManifest.xml"
ProtobufFormat="$(_ProtobufFormat)"
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
index e33e9215ff6..e554aec324c 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets
@@ -70,7 +70,7 @@ This file contains .NET 6+ calls to the and
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs
index 847aebeba55..7bdaf4c8589 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs
@@ -58,7 +58,7 @@ public class Aapt2Link : Aapt2 {
public string? UncompressedFileExtensions { get; set; }
- public string? AndroidSdkPlatform { get; set; }
+ public string AndroidApiLevel { get; set; } = "";
public string? VersionCodePattern { get; set; }
@@ -151,8 +151,12 @@ string [] GenerateCommandLineCommands (string ManifestFile, string? currentAbi,
string manifestDir = Path.Combine (Path.GetDirectoryName (ManifestFile), currentAbi != null ? currentAbi : "manifest");
Directory.CreateDirectory (manifestDir);
string manifestFile = Path.Combine (manifestDir, Path.GetFileName (ManifestFile));
+ string targetSdkVersion = AndroidApiLevel;
+ if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out Version v)) {
+ targetSdkVersion = v.Major.ToString (CultureInfo.InvariantCulture);
+ }
ManifestDocument manifest = new ManifestDocument (ManifestFile);
- manifest.TargetSdkVersion = AndroidSdkPlatform;
+ manifest.TargetSdkVersion = targetSdkVersion;
if (!VersionCodePattern.IsNullOrEmpty ()) {
try {
manifest.CalculateVersionCode (currentAbi, VersionCodePattern, VersionCodeProperties);
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CheckGoogleSdkRequirements.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CheckGoogleSdkRequirements.cs
index bdea41871d4..88694667e86 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/CheckGoogleSdkRequirements.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/CheckGoogleSdkRequirements.cs
@@ -1,15 +1,8 @@
#nullable enable
using System;
-using System.Collections.Generic;
-using Microsoft.Build.Utilities;
-using Microsoft.Build.Framework;
-using System.IO;
-using System.Linq;
-
-using Java.Interop.Tools.Cecil;
-using Xamarin.Android.Tools;
using Microsoft.Android.Build.Tasks;
+using Microsoft.Build.Framework;
namespace Xamarin.Android.Tasks
{
@@ -17,15 +10,8 @@ public class CheckGoogleSdkRequirements : AndroidTask
{
public override string TaskPrefix => "CGS";
- ///
- /// This will be blank for .NET 5 builds
- ///
- public string? TargetFrameworkVersion { get; set; }
-
- ///
- /// This is used instead of TargetFrameworkVersion for .NET 5 builds
- ///
- public int ApiLevel { get; set; }
+ [Required]
+ public string AndroidApiLevel { get; set; } = "";
[Required]
public string ManifestFile { get; set; } = "";
@@ -34,15 +20,18 @@ public override bool RunTask ()
{
ManifestDocument manifest = new ManifestDocument (ManifestFile);
- var compileSdk = TargetFrameworkVersion.IsNullOrEmpty () ?
- ApiLevel :
- MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
+ int? compileSdk = null;
+
+ if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
+ compileSdk = version.Major;
+ }
if (!int.TryParse (manifest.GetMinimumSdk (), out int minSdk)) {
minSdk = 1;
}
if (!int.TryParse (manifest.GetTargetSdk (), out int targetSdk)) {
- targetSdk = compileSdk ?? ApiLevel;
+ // 21 is minimum supported for .NET 6+, but should be better than putting 1 here.
+ targetSdk = compileSdk ?? 21;
}
//We should throw a warning if the targetSdkVersion is lower than compileSdkVersion(TargetFrameworkVersion).
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
index 86d7da7b765..bf709baf4c6 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs
@@ -47,8 +47,6 @@ public class GenerateJavaStubs : AndroidTask
public bool Debug { get; set; }
- [Required]
- public string AndroidSdkPlatform { get; set; } = "";
[Required]
public string OutputDirectory { get; set; } = "";
@@ -237,7 +235,7 @@ internal static Dictionary MaybeGetArchAssemblies (Dictionary
bool success = true;
if (generateJavaCode && RunCheckedBuild) {
- success = jcwGenerator.Generate (AndroidSdkPlatform, outputPath: Path.Combine (OutputDirectory, "src"), ApplicationJavaClass);
+ success = jcwGenerator.Generate (outputPath: Path.Combine (OutputDirectory, "src"), ApplicationJavaClass);
generatedJavaFiles = jcwGenerator.GeneratedJavaFiles;
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs
index 9d9782f64ce..dcece671899 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Microsoft.Android.Build.Tasks;
using Microsoft.Build.Framework;
@@ -19,7 +20,8 @@ public class GenerateMainAndroidManifest : AndroidTask
[Required]
public string AndroidRuntime { get; set; } = "";
public string? AndroidSdkDir { get; set; }
- public string? AndroidSdkPlatform { get; set; }
+ [Required]
+ public string AndroidApiLevel { get; set; } = "";
public string? ApplicationJavaClass { get; set; }
public string? ApplicationLabel { get; set; }
public string? BundledWearApplicationName { get; set; }
@@ -91,6 +93,11 @@ public override bool RunTask ()
IList MergeManifest (NativeCodeGenState codeGenState, Dictionary userAssemblies)
{
+ string targetSdkVersion = AndroidApiLevel;
+ if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out Version version)) {
+ targetSdkVersion = version.Major.ToString (CultureInfo.InvariantCulture);
+ }
+
var manifest = new ManifestDocument (ManifestTemplate) {
PackageName = PackageName,
VersionName = VersionName,
@@ -98,7 +105,7 @@ IList MergeManifest (NativeCodeGenState codeGenState, Dictionary "GAD";
[Required]
- public int AndroidApiLevel { get; set; }
+ public string AndroidApiLevel { get; set; } = "";
public string? ProductVersion { get; set; }
@@ -34,9 +34,20 @@ public override bool RunTask ()
constants.Add (new TaskItem ("__MOBILE__"));
constants.Add (new TaskItem ("__ANDROID__"));
- for (int i = 1; i <= AndroidApiLevel; ++i) {
+ if (!MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out var apiLevel)) {
+ return false;
+ }
+
+ for (int i = 1; i <= apiLevel.Major; ++i) {
constants.Add (new TaskItem ($"__ANDROID_{i}__"));
}
+ // TODO: We're just going to assume that there is a minor release for every major release from API-36.1 onward…
+ for (int i = 36; i < apiLevel.Major; ++i) {
+ constants.Add (new TaskItem ($"__ANDROID_{i}_1__"));
+ }
+ if (apiLevel.Minor != 0) {
+ constants.Add (new TaskItem ($"__ANDROID_{apiLevel.Major}_{apiLevel.Minor}__"));
+ }
AndroidDefineConstants = constants.ToArray ();
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs
index ea02a64f93e..61d407cb9b5 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs
@@ -148,8 +148,8 @@ int GetNdkApiLevel (NdkTools ndk, AndroidTargetArch arch)
level = manifest.MinSdkVersion.Value;
} else if (int.TryParse (MinimumSupportedApiLevel, out level)) {
// level already set
- } else if (int.TryParse (AndroidApiLevel, out level)) {
- // level already set
+ } else if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
+ level = version.Major;
} else {
// Probably not ideal!
level = MonoAndroidHelper.SupportedVersions.MaxStableVersion?.ApiLevel ?? 21;
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs
index ae82bde9f2e..8e6dfa519f3 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs
@@ -21,7 +21,7 @@ public class GetJavaPlatformJar : AndroidTask
private XNamespace androidNs = "http://schemas.android.com/apk/res/android";
[Required]
- public string AndroidSdkPlatform { get; set; } = "";
+ public string AndroidApiLevel { get; set; } = "";
public string? AndroidManifest { get; set; }
@@ -45,7 +45,7 @@ public class GetJavaPlatformJar : AndroidTask
public override bool RunTask ()
{
- var platform = AndroidSdkPlatform;
+ var platform = AndroidApiLevel;
XAttribute? target_sdk = null;
@@ -117,14 +117,14 @@ public override bool RunTask ()
string GetTargetSdkVersion (string target, XAttribute? target_sdk)
{
- string targetFrameworkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (AndroidSdkPlatform) ?? "";
+ string targetFrameworkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (AndroidApiLevel) ?? "";
string targetSdkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (target) ?? "";
// For .NET 6+ projects, use TargetPlatformVersion directly
string targetPlatformVersionDisplay = !TargetPlatformVersion.IsNullOrEmpty () ? TargetPlatformVersion : "";
- if (!int.TryParse (targetFrameworkVersion, out int frameworkSdk)) {
- // AndroidSdkPlatform is likely a *preview* API level; use it.
+ if (!MonoAndroidHelper.TryParseApiLevel (targetFrameworkVersion, out var frameworkSdk)) {
+ // AndroidApiLevel is likely a *preview* API level; use it.
Log.LogWarningForXmlNode (
code: "XA4211",
file: AndroidManifest,
@@ -138,8 +138,8 @@ string GetTargetSdkVersion (string target, XAttribute? target_sdk)
);
return targetFrameworkVersion;
}
- if (int.TryParse (targetSdkVersion, out int targetSdk) &&
- targetSdk < frameworkSdk) {
+ if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out var targetSdk) &&
+ targetSdk.Major < frameworkSdk.Major) {
Log.LogWarningForXmlNode (
code: "XA4211",
file: AndroidManifest,
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ReadAndroidManifest.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ReadAndroidManifest.cs
index 1d2d6392dba..9a31cd7487e 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/ReadAndroidManifest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/ReadAndroidManifest.cs
@@ -5,6 +5,8 @@
using System.IO;
using Xamarin.Android.Tools;
using Microsoft.Android.Build.Tasks;
+using System;
+using System.Globalization;
namespace Xamarin.Android.Tasks
{
@@ -66,7 +68,17 @@ public override bool RunTask ()
var attribute = uses_library.Attribute (androidNs + "name");
if (attribute != null && !attribute.Value.IsNullOrEmpty ()) {
var required = uses_library.Attribute (androidNs + "required")?.Value;
- var path = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{AndroidApiLevel}", "optional", $"{attribute.Value}.jar");
+ string apiLevel;
+ if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
+ if (version.Minor == 0) {
+ apiLevel = version.Major.ToString (CultureInfo.InvariantCulture);
+ } else {
+ apiLevel = version.ToString ();
+ }
+ } else {
+ apiLevel = AndroidApiLevel;
+ }
+ var path = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{apiLevel}", "optional", $"{attribute.Value}.jar");
if (File.Exists (path)) {
libraries.Add (new TaskItem (path));
} else {
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAndroidTooling.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAndroidTooling.cs
index 5ea189b934c..e01cbbbebd1 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAndroidTooling.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAndroidTooling.cs
@@ -81,7 +81,11 @@ public override bool RunTask ()
{
// This should be 31.0, 32.0, etc.
if (Version.TryParse (TargetPlatformVersion, out Version v)) {
- AndroidApiLevel = v.Major.ToString ();
+ if (v.Minor == 0) {
+ AndroidApiLevel = v.Major.ToString (CultureInfo.InvariantCulture);
+ } else {
+ AndroidApiLevel = v.ToString ();
+ }
} else {
AndroidApiLevel = GetMaxStableApiLevel ().ToString ();
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/CheckGoogleSdkRequirementsTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/CheckGoogleSdkRequirementsTests.cs
index 5d5e9a6d8c4..4948f9b733a 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/CheckGoogleSdkRequirementsTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/CheckGoogleSdkRequirementsTests.cs
@@ -49,7 +49,7 @@ public void CheckManifestIsOK ()
{
var task = new CheckGoogleSdkRequirements () {
BuildEngine = engine,
- TargetFrameworkVersion = "v9.0",
+ AndroidApiLevel = "28",
ManifestFile = CreateManiestFile (10, 28),
};
Assert.True (task.Execute (), "Task should have succeeded.");
@@ -62,7 +62,7 @@ public void CheckManifestTargetSdkLowerThanCompileSdk ()
{
var task = new CheckGoogleSdkRequirements () {
BuildEngine = engine,
- TargetFrameworkVersion = "v9.0",
+ AndroidApiLevel = "28",
ManifestFile = CreateManiestFile (10, 27),
};
Assert.True (task.Execute (), "Task should have succeeded.");
@@ -75,12 +75,12 @@ public void CheckManifestCompileSdkLowerThanTargetSdk ()
{
var task = new CheckGoogleSdkRequirements () {
BuildEngine = engine,
- TargetFrameworkVersion = "v8.1",
+ AndroidApiLevel = "27",
ManifestFile = CreateManiestFile (10, 28),
};
Assert.True (task.Execute (), "Task should have succeeded.");
Assert.AreEqual (0, errors.Count, "There should be 1 error reported.");
- Assert.AreEqual (1, warnings.Count, "There should be 0 warnings reported.");
+ Assert.AreEqual (1, warnings.Count, "There should be 1 warning reported.");
}
[Test]
@@ -88,12 +88,12 @@ public void CheckManifestMinSdkLowerThanTargetSdk ()
{
var task = new CheckGoogleSdkRequirements () {
BuildEngine = engine,
- TargetFrameworkVersion = "v8.1",
+ AndroidApiLevel = "27",
ManifestFile = CreateManiestFile (28, 27),
};
Assert.True (task.Execute (), "Task should have succeeded.");
Assert.AreEqual (0, errors.Count, "There should be 0 error reported.");
- Assert.AreEqual (1, warnings.Count, "There should be 1 warnings reported.");
+ Assert.AreEqual (1, warnings.Count, "There should be 1 warning reported.");
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/JCWGenerator.cs b/src/Xamarin.Android.Build.Tasks/Utilities/JCWGenerator.cs
index d466ab85b64..3bb8c5a6ee4 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/JCWGenerator.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/JCWGenerator.cs
@@ -53,17 +53,16 @@ public JCWGenerator (TaskLoggingHelper log, JCWGeneratorContext context)
public List GeneratedJavaFiles { get; } = [];
- public bool Generate (string androidSdkPlatform, string outputPath, string applicationJavaClass)
+ public bool Generate (string outputPath, string applicationJavaClass)
{
return ProcessTypes (
generateCode: true,
- androidSdkPlatform,
outputPath,
applicationJavaClass
);
}
- bool ProcessTypes (bool generateCode, string androidSdkPlatform, string? outputPath, string? applicationJavaClass)
+ bool ProcessTypes (bool generateCode, string? outputPath, string? applicationJavaClass)
{
if (generateCode && outputPath.IsNullOrEmpty ()) {
throw new ArgumentException ("must not be null or empty", nameof (outputPath));
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 6350bee47d2..f52d9f1c47e 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -1590,7 +1590,6 @@ because xbuild doesn't support framework reference assemblies.
GeneratedJavaFiles="@(_GeneratedJavaFiles)"
ErrorOnCustomJavaObject="$(AndroidErrorOnCustomJavaObject)"
Debug="$(AndroidIncludeDebugSymbols)"
- AndroidSdkPlatform="$(_AndroidApiLevel)"
OutputDirectory="$(IntermediateOutputPath)android"
PackageNamingPolicy="$(AndroidPackageNamingPolicy)"
ApplicationJavaClass="$(AndroidApplicationJavaClass)"
@@ -1633,7 +1632,7 @@ because xbuild doesn't support framework reference assemblies.