Skip to content

[build] Default .NET 11 to target net11.0-android37 only#11254

Draft
jonathanpeppers wants to merge 9 commits intomainfrom
jonathanpeppers/default-api-37-target
Draft

[build] Default .NET 11 to target net11.0-android37 only#11254
jonathanpeppers wants to merge 9 commits intomainfrom
jonathanpeppers/default-api-37-target

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Member

Stop building API 36.1 as a separate stable target and make net11.0-android37 the sole default target framework for .NET 11.

Changes:

  • Configuration.props: Set AndroidLatestStableApiLevel to 37, AndroidLatestStablePlatformId to 37.0 (explicit, since Google ships platform-37.0), framework version to v17.0. Unstable properties now reference stable (since they are the same). Updated AndroidLatestStableApiLevel2 comment example to 38.1.
  • AndroidToolchain.cs: Move isLatestStable from platform-36.1 to platform-37.0, remove isPreview flag
  • WorkloadManifest.in.json: Update workload packs from 36.1 to 37, add Mono/CoreCLR/NativeAOT runtime pack definitions for 37, remove 36.1 pack definitions
  • Xamarin.Android.Build.Tasks.targets: Use $(AndroidLatestStablePlatformId) for @SDK_PLATFORM_VERSION@ replacement instead of $(AndroidLatestStableApiLevel) (needed because ApiLevel=37 but PlatformId=37.0)
  • BuildTest.cs: Hardcode MinorApiLevelFallbackThrowsXA5207 to use 36.1 since 37.0 == 37 (no meaningful minor version distinction for this test scenario)

Note: AndroidLatestStablePlatformId is now explicitly set to 37.0 rather than defaulting to $(AndroidLatestStableApiLevel). This is because Google ships the platform as platform-37.0 (directory android-37.0), but the API level for TFMs and PublicAPI directories is just 37. Previous APIs (like 36 and 36.1) happened to have identical ApiLevel and PlatformId values.

jonathanpeppers and others added 9 commits April 30, 2026 10:41
Stop building API 36.1 as a separate stable target and make
net11.0-android37 the sole default target framework for .NET 11.

Changes:

- Configuration.props: Set AndroidLatestStableApiLevel to 37,
  AndroidLatestStablePlatformId to 37.0, framework version to v17.0.
  Unstable properties now reference stable (since they are the same).
- AndroidToolchain.cs: Move isLatestStable from platform-36.1 to
  platform-37.0, remove isPreview flag
- WorkloadManifest.in.json: Update workload packs from 36.1 to 37,
  add Mono/CoreCLR/NativeAOT runtime pack definitions for 37
- Xamarin.Android.Build.Tasks.targets: Use AndroidLatestStablePlatformId
  for SDK_PLATFORM_VERSION replacement (needed because ApiLevel=37 but
  PlatformId=37.0)
- BuildTest.cs: Hardcode MinorApiLevelFallbackThrowsXA5207 to use 36.1
  since 37.0 == 37 (no meaningful minor version distinction)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add acceptable-breakages-v17.0.txt for the v17.0 vs v16.1 API compat
check, and update acceptable-breakages-vReference-net11.0.txt with the
same breakages for the reference assembly comparison.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AndroidJavaRuntimeApiLevel was using AndroidLatestStableApiLevel (37),
but the Android SDK platform directory is android-37.0, not android-37.
Use AndroidLatestStablePlatformId (37.0) so java-runtime.csproj can
find android.jar.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Starting with API 37, Google ships the SDK platform as android-37.0
instead of android-37. Tests that hardcode platform.Major to construct
paths like "android-{platform.Major}/android.jar" fail because the
directory is actually android-37.0.

Add AndroidSdkResolver.GetPlatformDirectoryName() and GetAndroidJarPath()
helpers that check for both directory names and return the correct one.
Update Aapt2Tests and ManagedResourceParserTests to use these helpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
net11.0-android36.1 is no longer valid on .NET 11 (API 37 is the only
supported target), so BundledVersions.targets silently upgrades to
API 37 and XA5207 never fires. Use net10.0-android36.1 instead since
36.1 is the supported API level for .NET 10.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Starting with API 37, Google ships the SDK platform directory as
android-37.0 instead of android-37. Gradle compileSdk = 37 (integer)
looks for platforms/android-37 which does not exist.

Add GetCompileSdkGradleLine() helper that detects when the platform
directory uses the ".0" suffix and generates compileSdkPreview =
"android-37.0" instead of compileSdk = 37.

This fixes all AndroidGradleProjectTests (BuildApp, BindLibrary,
BindFacebook, BuildIncremental, BuildMultipleModules, etc.).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previous approach tried filesystem detection which was unreliable on
CI. Instead, use the known fact that API 37+ always ships as
android-{Major}.0 (e.g. android-37.0). For these API levels, generate
compileSdkPreview = "android-37.0" in the Gradle build file instead
of compileSdk = 37 (which looks for android-37 that does not exist).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The fundamental fix: xaprepare now creates a symlink from android-37
to android-37.0 after installing the SDK platform. This ensures Gradle
(which uses compileSdk = 37 and looks for android-37), our MSBuild
tasks, and all other tools can find the platform directory regardless
of whether they use the integer or ".0" form.

This reverts the compileSdkPreview approach (which was unreliable) in
favor of making both directory names work.

Also set xamarin_manifest_needs_updating = true in
AndroidDependenciesTests since the Xamarin manifest does not yet have
API 37 entries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AGP 9.1.1 (April 2026) natively supports compileSdk = 37 with the
android-37.0 platform directory. No symlinks or compileSdkPreview
workarounds needed.

- Bump default AGP from 9.1.0 to 9.1.1
- Fix BindLibraryWithMultipleGradleVersions: AGP 9.0.0 only supports
  up to compileSdk 36, so hardcode that instead of using the default
- Remove xaprepare symlink creation (no longer needed)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant