Skip to content

[pull] main from dotnet:main - #1161

Merged
pull[bot] merged 4 commits into
MaxMood96:mainfrom
dotnet:main
Sep 12, 2025
Merged

pull[bot] merged 4 commits into
MaxMood96:mainfrom
dotnet:main

Conversation

@pull

@pull pull Bot commented Sep 12, 2025 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.3)

Can you help keep this open source service alive? 💖 Please sponsor : )

dotnet-maestro Bot and others added 4 commits September 12, 2025 08:14
Changes: a618557...1dcfb6f

Update: Microsoft.NET.Sdk.Android.Manifest-9.0.100 From Version 35.0.101 -> To Version 35.0.105
Fixes: #10455

Implements a minimal Android host for NativeAOT applications. The goal is to create
a runtime environment that is as compatible with Xamarin.Android / .NET for Android
applications using MonoVM or CoreCLR as possible. This PR implements the very basics:

  * Support for pre-loading of JNI libraries
  * Support for setting of the application environment variables (via `<AndroidEnvironment>`)
  * Support for the CoreCLR GC bridge

An important element that's currently missing is linking `libc++` statically into the runtime,
instead we include the shared `libc++` from the NDK. The reason for this is that NativeAOT
build task references a compatibility C++ library which produces conflicts with the static 
`libc++` one when attempting to link. This issue will be fixed in a separate PR.
Context: https://developer.android.com/about/versions/16/qpr2/
Context: https://android-developers.googleblog.com/2025/08/android-16-qpr2-beta-1-is-here.html

Changes: dotnet/java-interop@a5d7370...f07b538

  * dotnet/java-interop@f07b5385: [generator] Support major.minor API levels (dotnet/java-interop#1360)

Android 16 Quarterly Platform Release 2 (QPR2) Beta 1 has been released.

  * [API-CANARY Beta 1 vs. API-36][0]

The Android 16 QPR2 Beta 1 [Announcement][1] suggests the following
timeline:

  * Aug/Sep: Unstable Betas
  * Oct: Stable beta with a [Platform Stability milestone][2]
  * ???: Final

Android 16 QPR2 adds an additional wrinkle: "minor" SDK versions are
now A Thing™; see:

  * [`<uses-sdk/>`][3]:

    > It's not possible to specify that an app either targets or requires a minor SDK version.

  * [Using new APIs with major and minor releases][4]:

    > The new [`SDK_INT_FULL`][5] constant can be used for API checks…
    >
    >     if (SDK_INT_FULL >= VERSION_CODES_FULL.[MAJOR or MINOR RELEASE]) {
    >       // Use APIs introduced in a major or minor release
    >     }
    >
    > You can also use the [`Build.getMinorSdkVersion()`][6] method to
    > get just the minor SDK version:
    >
    >     minorSdkVersion = Build.getMinorSdkVersion(Build.VERSION_CODES_FULL.BAKLAVA);

What these mean is that "Android 16 QPR2" *will not* be API-37.
It will be "API-36.1": `<uses-sdk/>` will specify e.g.
`android:targetSdkVersion="36"` (***not*** `37`), and runtime guards
against Android 16 QPR2 will need to check against e.g.
[`Build.VERSION_CODES_FULL#BAKLAVA_1`][7], documented as "Android 36.1".

This in turn means that our historical approach to adding new API
levels does not immediately apply.  API-CANARY *will not be* API-37.
`net10.0-android37.0` -- when it exists -- will not bind API-CANARY;
it will bind Android 17, presumably in 2026.

So what do we call it?

We will need to call it `net10.0-android36.1`:

  * `net10.0-android36.0` is "plain"/"original" API-36.
  * `net10.0-android36.1` will be Android 16 QPR2 / API-CANARY.

This will be usable in its preview form to `main` users
who explicitly target `net10.0-android36.1`.

This is unlikely to be released in .NET 10 GA (2025-Nov) as
`net10.0-android36.1`.

~~ Changes: Minor SDK Versions ~~

"Minor" SDK versions are something we've never had to support before,
so lots of associated changes to the build system and tooling are
required to support it.  Among the changes is the assumption that an
API level is "just" an int.

Update `create-android-api.csproj` to use `java-source-utils.jar`
instead of `param-name-importer.dll`, as `param-name-importer.dll`
was not able to import API-CANARY's `android-stubs-src.jar`:

	create-android-api failed with 2 error(s) (1.0s)
	  EXEC : error (3050: 47) Invalid character: '''.

More specifically:

	% dotnet bin/Debug/lib/packs/Microsoft.Android.Sdk.Darwin/36.0.0/tools/param-name-importer.dll \
	  "-source-stub-zip=$HOME/android-toolchain/sdk/platforms/android-CANARY/android-stubs-src.jar" \
	  "-output-text=src/Mono.Android/Profiles/api-CANARY.params.txt" \
	  -verbose -framework-only
	…
	java/lang/Character.java
	Error (3050:47) Invalid character: '''.

As `param-name-importer.dll` uses an Irony-based Java source parser,
and *we have a better* Java source parser which can *also* output the
`param-name-importer.dll` text format in `java-source-utils.jar`
use `java-source-utils.jar` instead.

Update `GenerateSupportedPlatforms.cs` to look at
`AndroidVersion.VersionCodeFull` instead of `AndroidVersion.ApiLevel`.
This allows minor SDK versions to be present in
`@(AndroidSdkSupportedTargetPlatformVersion)`.

Update `GeneratedMonoAndroidProjitemsFile.cs` so that the generated
`bin\Build$(Configuration)\Mono.Android.Apis.projitems` file contains
`%(AndroidApiInfo.VersionCodeFull)` item metadata.

Update `Mono.Android.targets` so that the generated `AndroidApiInfo.xml`
file contains `<VersionCodeFull/>`, based on `%(VersionCodeFull)`.

Add `InstallAndRunTests.DotNetInstallAndRunPreviewAPILevels()`, which
uses the new `net10.0-android36.1` target framework and references
one of the new Preview APIs.

Add a new set of `PublicAPI.*.txt` files so that the Public API
analyzer can "do its thing".
`src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Shipped.txt`
is based on the union of `PublicAPI.Shipped.txt` and
`PublicApi.Unshipped.txt` for API-36.

Update the workloads to use `Microsoft.Android.Runtime.Mono.36.[RID]`
packs.  Fixes:

	…/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(119,5): error NETSDK1181: Error getting pack version: Pack 'Microsoft.Android.Runtime.Mono.36.1.android-arm64' was not present in workload manifests.
	…/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(119,5): error NETSDK1181: Error getting pack version: Pack 'Microsoft.Android.Runtime.Mono.36.1.android-x64' was not present in workload manifests.

Update `XABuildConfig` so that all `*ApiLevel` fields are now
`System.Version`, ***not*** `int`.  This allows them to properly
contain minor values.  This in turn impacts "everything", changing
many `int`s to `Versions`s.

Additionally, update `XASdkTests.DotNetTargetFrameworks` to *not*
always append `.0`.  The use of `Version` handles this for us, nicely.

Update `build.gradle` generation within unit tests to ensure that
`compileSdk` et. al are `int` values.

~~ Changes: Disable lint checks for `@(AndroidGradleProject)` Tests ~~

Some `@(AndroidGradleProject)` tests were failing on CI:

	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000: FAILURE: Build failed with an exception.
	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000:
	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000: * What went wrong:
	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000: Execution failed for task ':TestModule:lintVitalAnalyzeRelease'.
	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000: > A failure occurred while executing com.android.build.gradle.internal.lint.AndroidLintWorkAction
	…/Microsoft.Android.Sdk.Bindings.Gradle.targets(83,5): error XAGRDL0000:    > For input string: "36.0"

After a fair bit of digging around -- read the `.binlog`, find
the `gradlew` invocation, *manually* run the `gradlew` invocation
while adding `-d` go get diagnostic output, which in turn provides
the `lint` invocation -- we see that `lint` is crashing with:

	Exception in thread "main" java.lang.NumberFormatException: For input string: "36.0"
		at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
		at java.base/java.lang.Integer.parseInt(Integer.java:668)
		at java.base/java.lang.Integer.parseInt(Integer.java:786)
		at com.android.tools.lint.client.api.SimplePlatformLookup$Companion.platformFromSourceProp(SimplePlatformLookup.kt:256)
		at com.android.tools.lint.client.api.SimplePlatformLookup$Companion.addPlatforms(SimplePlatformLookup.kt:146)
		at com.android.tools.lint.client.api.SimplePlatformLookup$Companion.access$addPlatforms(SimplePlatformLookup.kt:113)
		at com.android.tools.lint.client.api.SimplePlatformLookup.<init>(SimplePlatformLookup.kt:65)
		at com.android.tools.lint.client.api.SimplePlatformLookup$Companion.get(SimplePlatformLookup.kt:118)
		at com.android.tools.lint.client.api.LintClient.getPlatformLookup(LintClient.kt:1045)
		at com.android.tools.lint.client.api.LintClient.getCompileTarget(LintClient.kt:1063)
		at com.android.tools.lint.detector.api.Project.getBuildTarget(Project.java:959)
		at com.android.tools.lint.LintCliClient$pickBuildTarget$2.invoke(LintCliClient.kt:1464)
		at com.android.tools.lint.LintCliClient$pickBuildTarget$2.invoke(LintCliClient.kt:1464)
		at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:210)
		at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:170)
		at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:194)
		at com.android.tools.lint.LintCliClient.pickBuildTarget(LintCliClient.kt:1947)
		at com.android.tools.lint.LintCliClient.getBootClassPath(LintCliClient.kt:1443)
		at com.android.tools.lint.Main$MainLintClient.getBootClassPath(Main.java:805)
		at com.android.tools.lint.LintCliClient.initializeProjects(LintCliClient.kt:1421)
		at com.android.tools.lint.client.api.LintClient.performInitializeProjects$lint_api(LintClient.kt:1009)
		at com.android.tools.lint.client.api.LintDriver.initializeProjectRoots(LintDriver.kt:569)
		at com.android.tools.lint.client.api.LintDriver.doAnalyze(LintDriver.kt:484)
		at com.android.tools.lint.client.api.LintDriver.analyzeOnly(LintDriver.kt:443)
		at com.android.tools.lint.LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:233)
		at com.android.tools.lint.LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:233)
		at com.android.tools.lint.LintCliClient.run(LintCliClient.kt:275)
		at com.android.tools.lint.LintCliClient.run$default(LintCliClient.kt:258)
		at com.android.tools.lint.LintCliClient.analyzeOnly(LintCliClient.kt:233)
		at com.android.tools.lint.Main.run(Main.java:1761)
		at com.android.tools.lint.Main.run(Main.java:284)
		at com.android.tools.lint.Main.main(Main.java:221)

Of note is `SimplePlatformLookup$Companion.platformFromSourceProp()`,
which reads the `source.properties` files within
`$ANDROID_HOME/platforms/android-*/source.properties`.

The problem is that API-CANARY's `source.properties` contains:

	AndroidVersion.ApiLevel=36.0

which `lint` doesn't like.

`lint` has been fixed to support minor SDK versions, e.g.

  * https://cs.android.com/android-studio/platform/tools/base/+/5d246c720b206b7075a826d1bd4549882dd7c085

However, that commit was merged in 2025-May, while the latest
cmdline-tools package is 19.0, released in 2025-March.

Which means we have no `lint` package which has the fix!

As a quick workaround, *disable* lint checks in the unit tests,
by adding the block:

	android {
	  lint {
	    checkReleaseBuilds = false
	  }
	}

This *should* prevent `lint` from running at all, thus "fixing"
the `NumberFormatException`.

Co-authored-by: Jonathan Peppers <[email protected]>

[0]: https://developer.android.com/sdk/api_diff/b-1-beta1/changes
[1]: https://android-developers.googleblog.com/2025/08/android-16-qpr2-beta-1-is-here.html
[2]: https://developer.android.com/about/versions/16/qpr2/overview#platform-stability
[3]: https://developer.android.com/guide/topics/manifest/uses-sdk-element
[4]: https://developer.android.com/about/versions/16/features#using-new
[5]: https://developer.android.com/reference/android/os/Build.VERSION#SDK_INT_FULL
[6]: https://developer.android.com/reference/android/os/Build#getMinorSdkVersion(int)
[7]: https://developer.android.com/reference/android/os/Build.VERSION_CODES_FULL#BAKLAVA_1
@pull pull Bot locked and limited conversation to collaborators Sep 12, 2025
@pull pull Bot added the ⤵️ pull label Sep 12, 2025
@pull
pull Bot merged commit fca76a3 into MaxMood96:main Sep 12, 2025
1 check passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants