Skip to content

Commit ec3d578

Browse files
[xabt] additional fixes for non-integer API levels (#10536)
We found the following errors with many `javac` errors: class MyTextObjectFont : Android.Graphics.Pdf.Component.PdfPageTextObjectFont { public MyTextObjectFont(Android.Graphics.Pdf.Component.PdfPageTextObjectFont font) : base(font) { } } Such as: obj\Debug\net10.0-android36.1\android\src\crc643b87557a63e7c027\MainActivity_MyTextObjectFont.java(5,40): error JAVAC0000: error: package android.graphics.pdf.component does not exist extends android.graphics.pdf.component.PdfPageTextObjectFont This appears to be caused by the use of: "C:\Program Files (x86)\Android\android-sdk\platforms\android-36\android.jar" When the build *should* be using: "C:\Program Files (x86)\Android\android-sdk\platforms\android-36.1\android.jar" Update various MSBuild logic to handle non-integer API levels. **API Level Property Standardization** * Replaced `AndroidSdkPlatform` with `AndroidApiLevel` in all relevant MSBuild targets and task classes, including `Aapt2Link`, `GenerateMainAndroidManifest`, `GetJavaPlatformJar`, and others. **Parsing and Usage Improvements** * Updated logic to parse `AndroidApiLevel` using `MonoAndroidHelper.TryParseApiLevel` where necessary, supporting both major and minor versions and defaulting to sensible values when parsing fails. **Code Cleanup and Refactoring** * Removed unused or obsolete parameters and code paths related to `AndroidSdkPlatform` in several classes and methods, such as `GenerateJavaStubs` and `JCWGenerator`. * Updated test cases for `CheckGoogleSdkRequirements` to use `AndroidApiLevel` instead of `TargetFrameworkVersion`, and corrected assertions for warnings and errors. **MSBuild Targets Updates** * Modified MSBuild target files to use the new `AndroidApiLevel` property, ensuring that all build steps and tooling reference the correct property name.
1 parent 267e129 commit ec3d578

File tree

16 files changed

+90
-58
lines changed

16 files changed

+90
-58
lines changed

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
234234
CreatePackagePerAbi="$(AndroidCreatePackagePerAbi)"
235235
AssetsDirectory="$(MonoAndroidAssetsDirIntermediate)"
236236
AdditionalAndroidAssetPaths="@(LibraryAssetDirectories)"
237-
AndroidSdkPlatform="$(_AndroidApiLevel)"
237+
AndroidApiLevel="$(_AndroidApiLevel)"
238238
JavaDesignerOutputDirectory="$(AaptTemporaryDirectory)"
239239
ManifestFiles="$(IntermediateOutputPath)android\AndroidManifest.xml"
240240
ProtobufFormat="$(_ProtobufFormat)"

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ This file contains .NET 6+ calls to the <ValidateJavaVersion/> and
7070
<Target Name="_CheckGoogleSdkRequirements"
7171
Condition="Exists('$(IntermediateOutputPath)android\AndroidManifest.xml') And '$(AndroidEnableGooglePlayStoreChecks)' == 'true' ">
7272
<CheckGoogleSdkRequirements
73-
ApiLevel="$(_AndroidApiLevel)"
73+
AndroidApiLevel="$(_AndroidApiLevel)"
7474
ManifestFile="$(IntermediateOutputPath)android\AndroidManifest.xml"
7575
/>
7676
</Target>

src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class Aapt2Link : Aapt2 {
5858

5959
public string? UncompressedFileExtensions { get; set; }
6060

61-
public string? AndroidSdkPlatform { get; set; }
61+
public string AndroidApiLevel { get; set; } = "";
6262

6363
public string? VersionCodePattern { get; set; }
6464

@@ -151,8 +151,12 @@ string [] GenerateCommandLineCommands (string ManifestFile, string? currentAbi,
151151
string manifestDir = Path.Combine (Path.GetDirectoryName (ManifestFile), currentAbi != null ? currentAbi : "manifest");
152152
Directory.CreateDirectory (manifestDir);
153153
string manifestFile = Path.Combine (manifestDir, Path.GetFileName (ManifestFile));
154+
string targetSdkVersion = AndroidApiLevel;
155+
if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out Version v)) {
156+
targetSdkVersion = v.Major.ToString (CultureInfo.InvariantCulture);
157+
}
154158
ManifestDocument manifest = new ManifestDocument (ManifestFile);
155-
manifest.TargetSdkVersion = AndroidSdkPlatform;
159+
manifest.TargetSdkVersion = targetSdkVersion;
156160
if (!VersionCodePattern.IsNullOrEmpty ()) {
157161
try {
158162
manifest.CalculateVersionCode (currentAbi, VersionCodePattern, VersionCodeProperties);

src/Xamarin.Android.Build.Tasks/Tasks/CheckGoogleSdkRequirements.cs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,17 @@
11
#nullable enable
22

33
using System;
4-
using System.Collections.Generic;
5-
using Microsoft.Build.Utilities;
6-
using Microsoft.Build.Framework;
7-
using System.IO;
8-
using System.Linq;
9-
10-
using Java.Interop.Tools.Cecil;
11-
using Xamarin.Android.Tools;
124
using Microsoft.Android.Build.Tasks;
5+
using Microsoft.Build.Framework;
136

147
namespace Xamarin.Android.Tasks
158
{
169
public class CheckGoogleSdkRequirements : AndroidTask
1710
{
1811
public override string TaskPrefix => "CGS";
1912

20-
/// <summary>
21-
/// This will be blank for .NET 5 builds
22-
/// </summary>
23-
public string? TargetFrameworkVersion { get; set; }
24-
25-
/// <summary>
26-
/// This is used instead of TargetFrameworkVersion for .NET 5 builds
27-
/// </summary>
28-
public int ApiLevel { get; set; }
13+
[Required]
14+
public string AndroidApiLevel { get; set; } = "";
2915

3016
[Required]
3117
public string ManifestFile { get; set; } = "";
@@ -34,15 +20,18 @@ public override bool RunTask ()
3420
{
3521
ManifestDocument manifest = new ManifestDocument (ManifestFile);
3622

37-
var compileSdk = TargetFrameworkVersion.IsNullOrEmpty () ?
38-
ApiLevel :
39-
MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
23+
int? compileSdk = null;
24+
25+
if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
26+
compileSdk = version.Major;
27+
}
4028

4129
if (!int.TryParse (manifest.GetMinimumSdk (), out int minSdk)) {
4230
minSdk = 1;
4331
}
4432
if (!int.TryParse (manifest.GetTargetSdk (), out int targetSdk)) {
45-
targetSdk = compileSdk ?? ApiLevel;
33+
// 21 is minimum supported for .NET 6+, but should be better than putting 1 here.
34+
targetSdk = compileSdk ?? 21;
4635
}
4736

4837
//We should throw a warning if the targetSdkVersion is lower than compileSdkVersion(TargetFrameworkVersion).

src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ public class GenerateJavaStubs : AndroidTask
4747

4848
public bool Debug { get; set; }
4949

50-
[Required]
51-
public string AndroidSdkPlatform { get; set; } = "";
5250
[Required]
5351
public string OutputDirectory { get; set; } = "";
5452

@@ -237,7 +235,7 @@ internal static Dictionary<string, ITaskItem> MaybeGetArchAssemblies (Dictionary
237235
bool success = true;
238236

239237
if (generateJavaCode && RunCheckedBuild) {
240-
success = jcwGenerator.Generate (AndroidSdkPlatform, outputPath: Path.Combine (OutputDirectory, "src"), ApplicationJavaClass);
238+
success = jcwGenerator.Generate (outputPath: Path.Combine (OutputDirectory, "src"), ApplicationJavaClass);
241239

242240
generatedJavaFiles = jcwGenerator.GeneratedJavaFiles;
243241
}

src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections.Concurrent;
44
using System.Collections.Generic;
5+
using System.Globalization;
56
using System.Linq;
67
using Microsoft.Android.Build.Tasks;
78
using Microsoft.Build.Framework;
@@ -19,7 +20,8 @@ public class GenerateMainAndroidManifest : AndroidTask
1920
[Required]
2021
public string AndroidRuntime { get; set; } = "";
2122
public string? AndroidSdkDir { get; set; }
22-
public string? AndroidSdkPlatform { get; set; }
23+
[Required]
24+
public string AndroidApiLevel { get; set; } = "";
2325
public string? ApplicationJavaClass { get; set; }
2426
public string? ApplicationLabel { get; set; }
2527
public string? BundledWearApplicationName { get; set; }
@@ -91,14 +93,19 @@ public override bool RunTask ()
9193

9294
IList<string> MergeManifest (NativeCodeGenState codeGenState, Dictionary<string, ITaskItem> userAssemblies)
9395
{
96+
string targetSdkVersion = AndroidApiLevel;
97+
if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out Version version)) {
98+
targetSdkVersion = version.Major.ToString (CultureInfo.InvariantCulture);
99+
}
100+
94101
var manifest = new ManifestDocument (ManifestTemplate) {
95102
PackageName = PackageName,
96103
VersionName = VersionName,
97104
ApplicationLabel = ApplicationLabel ?? PackageName,
98105
Placeholders = ManifestPlaceholders,
99106
Resolver = codeGenState.Resolver,
100107
SdkDir = AndroidSdkDir,
101-
TargetSdkVersion = AndroidSdkPlatform,
108+
TargetSdkVersion = targetSdkVersion,
102109
MinSdkVersion = MonoAndroidHelper.ConvertSupportedOSPlatformVersionToApiLevel (SupportedOSPlatformVersion).ToString (),
103110
Debug = Debug,
104111
MultiDex = MultiDex,

src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidDefineConstants.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class GetAndroidDefineConstants : AndroidTask
1515
public override string TaskPrefix => "GAD";
1616

1717
[Required]
18-
public int AndroidApiLevel { get; set; }
18+
public string AndroidApiLevel { get; set; } = "";
1919

2020
public string? ProductVersion { get; set; }
2121

@@ -34,9 +34,20 @@ public override bool RunTask ()
3434
constants.Add (new TaskItem ("__MOBILE__"));
3535
constants.Add (new TaskItem ("__ANDROID__"));
3636

37-
for (int i = 1; i <= AndroidApiLevel; ++i) {
37+
if (!MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out var apiLevel)) {
38+
return false;
39+
}
40+
41+
for (int i = 1; i <= apiLevel.Major; ++i) {
3842
constants.Add (new TaskItem ($"__ANDROID_{i}__"));
3943
}
44+
// TODO: We're just going to assume that there is a minor release for every major release from API-36.1 onward…
45+
for (int i = 36; i < apiLevel.Major; ++i) {
46+
constants.Add (new TaskItem ($"__ANDROID_{i}_1__"));
47+
}
48+
if (apiLevel.Minor != 0) {
49+
constants.Add (new TaskItem ($"__ANDROID_{apiLevel.Major}_{apiLevel.Minor}__"));
50+
}
4051

4152
AndroidDefineConstants = constants.ToArray ();
4253

src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ int GetNdkApiLevel (NdkTools ndk, AndroidTargetArch arch)
148148
level = manifest.MinSdkVersion.Value;
149149
} else if (int.TryParse (MinimumSupportedApiLevel, out level)) {
150150
// level already set
151-
} else if (int.TryParse (AndroidApiLevel, out level)) {
152-
// level already set
151+
} else if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
152+
level = version.Major;
153153
} else {
154154
// Probably not ideal!
155155
level = MonoAndroidHelper.SupportedVersions.MaxStableVersion?.ApiLevel ?? 21;

src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class GetJavaPlatformJar : AndroidTask
2121
private XNamespace androidNs = "http://schemas.android.com/apk/res/android";
2222

2323
[Required]
24-
public string AndroidSdkPlatform { get; set; } = "";
24+
public string AndroidApiLevel { get; set; } = "";
2525

2626
public string? AndroidManifest { get; set; }
2727

@@ -45,7 +45,7 @@ public class GetJavaPlatformJar : AndroidTask
4545

4646
public override bool RunTask ()
4747
{
48-
var platform = AndroidSdkPlatform;
48+
var platform = AndroidApiLevel;
4949

5050
XAttribute? target_sdk = null;
5151

@@ -117,14 +117,14 @@ public override bool RunTask ()
117117

118118
string GetTargetSdkVersion (string target, XAttribute? target_sdk)
119119
{
120-
string targetFrameworkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (AndroidSdkPlatform) ?? "";
120+
string targetFrameworkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (AndroidApiLevel) ?? "";
121121
string targetSdkVersion = MonoAndroidHelper.SupportedVersions.GetIdFromApiLevel (target) ?? "";
122122

123123
// For .NET 6+ projects, use TargetPlatformVersion directly
124124
string targetPlatformVersionDisplay = !TargetPlatformVersion.IsNullOrEmpty () ? TargetPlatformVersion : "";
125125

126-
if (!int.TryParse (targetFrameworkVersion, out int frameworkSdk)) {
127-
// AndroidSdkPlatform is likely a *preview* API level; use it.
126+
if (!MonoAndroidHelper.TryParseApiLevel (targetFrameworkVersion, out var frameworkSdk)) {
127+
// AndroidApiLevel is likely a *preview* API level; use it.
128128
Log.LogWarningForXmlNode (
129129
code: "XA4211",
130130
file: AndroidManifest,
@@ -138,8 +138,8 @@ string GetTargetSdkVersion (string target, XAttribute? target_sdk)
138138
);
139139
return targetFrameworkVersion;
140140
}
141-
if (int.TryParse (targetSdkVersion, out int targetSdk) &&
142-
targetSdk < frameworkSdk) {
141+
if (MonoAndroidHelper.TryParseApiLevel (targetSdkVersion, out var targetSdk) &&
142+
targetSdk.Major < frameworkSdk.Major) {
143143
Log.LogWarningForXmlNode (
144144
code: "XA4211",
145145
file: AndroidManifest,

src/Xamarin.Android.Build.Tasks/Tasks/ReadAndroidManifest.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.IO;
66
using Xamarin.Android.Tools;
77
using Microsoft.Android.Build.Tasks;
8+
using System;
9+
using System.Globalization;
810

911
namespace Xamarin.Android.Tasks
1012
{
@@ -66,7 +68,17 @@ public override bool RunTask ()
6668
var attribute = uses_library.Attribute (androidNs + "name");
6769
if (attribute != null && !attribute.Value.IsNullOrEmpty ()) {
6870
var required = uses_library.Attribute (androidNs + "required")?.Value;
69-
var path = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{AndroidApiLevel}", "optional", $"{attribute.Value}.jar");
71+
string apiLevel;
72+
if (MonoAndroidHelper.TryParseApiLevel (AndroidApiLevel, out Version version)) {
73+
if (version.Minor == 0) {
74+
apiLevel = version.Major.ToString (CultureInfo.InvariantCulture);
75+
} else {
76+
apiLevel = version.ToString ();
77+
}
78+
} else {
79+
apiLevel = AndroidApiLevel;
80+
}
81+
var path = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{apiLevel}", "optional", $"{attribute.Value}.jar");
7082
if (File.Exists (path)) {
7183
libraries.Add (new TaskItem (path));
7284
} else {

0 commit comments

Comments
 (0)