-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Add NativeAOT on Android test #118037
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add NativeAOT on Android test #118037
Conversation
Tagging subscribers to this area: @akoeplinger, @matouskozak, @simonrozsival |
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
Outdated
Show resolved
Hide resolved
@dotnet/samsung Could you please take a look? These changes may be related to riscv64. |
/azp run runtime-androidemulator |
Azure Pipelines successfully started running 1 pipeline(s). |
- Don't use BundleDir for android bundle dir: This is PublishDir when TestSingleFile=true (which it is). Android deletes this dir before packaging, deleting the files that were just published. - Don't add the singleFileTestRunner.cs when the test sets IsFunctionalTest=true - Don't run regular nativeaot smoke tests on android yet. - Enable android tests to publish as libs when TestSingleFile=true (default when TestNativeAOT=true)
/azp run runtime-androidemulator |
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for running NativeAOT (Native Ahead-of-Time) compiled applications on Android. The implementation creates a shared library that exports the required JNI methods expected by the Android test infrastructure, eliminating the need for the monodroid runtime while maintaining compatibility with existing test frameworks.
Key changes include:
- Added NativeAOT-specific Android test project and JNI interop layer
- Updated build infrastructure to support NativeAOT runtime flavor
- Modified Android app builder to handle NativeAOT library generation and packaging
Reviewed Changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs | Simple test program that validates console output and cryptography functionality |
src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj | Project file configuring NativeAOT compilation with required JNI template inclusion |
src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs | JNI interop layer implementing required Android runtime interface methods |
src/tasks/AndroidAppBuilder/Templates/MonoRunner.java | Updated Java template to support dynamic library loading statements |
src/tasks/AndroidAppBuilder/ApkBuilder.cs | Enhanced APK builder with NativeAOT runtime support and library packaging |
src/mono/msbuild/android/build/AndroidBuild.targets | Updated build targets to handle NativeAOT runtime flavor and dependencies |
src/mono/msbuild/android/build/AndroidBuild.props | Added Android NDK toolchain configuration and NativeAOT build dependencies |
src/libraries/tests.proj | Modified test project inclusion logic for NativeAOT Android tests |
src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp | Added missing thread.inl include for Java interop |
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets | Extended cross-compilation support for android- RID prefix |
src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets | Added Android bionic libc flavor detection |
eng/testing/tests.singlefile.targets | Conditional OutputType and compilation adjustments for Android NativeAOT |
eng/testing/tests.android.targets | Removed redundant AndroidBundleDir property assignment |
eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml | Added CI pipeline job for NativeAOT Android emulator testing |
eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml | Added CI pipeline job for NativeAOT Android device testing |
/azp run runtime-androidemulator |
Azure Pipelines successfully started running 1 pipeline(s). |
There's one thing that we should still fix: --- a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
@@ -130,7 +130,9 @@ public override bool Execute()
continue;
}
- if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true)
+ if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true &&
+ !assemblyFileName.EndsWith(".jar", StringComparison.OrdinalIgnoreCase) &&
+ !assemblyFileName.EndsWith(".dex", StringComparison.OrdinalIgnoreCase))
{
// Skip the native components of the runtime pack, we don't need them for NativeAOT.
assembliesToSkipPublish.Add(taskItem); The native assets of the Android runtime files now contain the .jar/.dex files for libSystem.Security.Cryptography.Android. We should not strip them in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested that it makes the Android runtime pack into functional state that can be consumed on the workload side and used to build a whole app. Obviously there's still work that has to be done on the consumption side (dotnet/android) but having an end-to-end scenrio running is a good start:

One thing that still needs to be resolved is who is responsible for exporting the JNI symbol for Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate
in case of the builds that link the crypto libraries statically. Presumably that can and will be done on the Android workload side with something like <IlcArg Include="--export-dynamic-symbol:Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate" />
.
@filipnavara maybe this will solve the JNI export problem for crypto: #108513 |
Yes, that's part of the solution. There's an issue for CoreCLR integration filed at dotnet/android#10324 that has a bit more context. |
/azp run runtime-androidemulator |
Azure Pipelines successfully started running 1 pipeline(s). |
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
Show resolved
Hide resolved
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
Show resolved
Hide resolved
/ba-g failures are unrelated |
Adds a project to run a NativeAOT shared library on Android.
The android test builds a single native library that exports the methods that are expected by the monodroid tests (InitRuntime, SetEnv, ExecEntryPoint, FreeUnmanagedResources). JNI struct definitions are copied to get arg strings from the JNIEnv object.
ApkBuilder no longer needs to compile the monodroid native library, but it does need to add the java .jar from the cryptography library to the apk bundle in order to run crypto operations.
Build targets were updated to account for the new NativeAOT tests, and a new job was added for NativeAOT on android tests.