From 060ffd37f8bf38f2ba6cf69228bd083cbdb15b92 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 21 Jul 2025 14:14:47 -0700
Subject: [PATCH 01/33] NativeAOT Android test working locally
---
RunMyTest.sh | 3 +
eng/Subsets.props | 5 +-
eng/targetingpacks.targets | 4 +-
...soft.DotNet.ILCompiler.SingleEntry.targets | 3 +-
.../Microsoft.NETCore.Native.Unix.targets | 5 +-
.../tools/Common/CommandLineHelpers.cs | 1 +
.../msbuild/android/build/AndroidBuild.props | 3 +-
.../android/build/AndroidBuild.targets | 3 +
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 150 ++++---
.../Templates/MonoRunner.java | 3 +-
.../Templates/monodroid-nativeaot.cs | 422 ++++++++++++++++++
.../Android/AndroidProject.cs | 2 +-
.../Android.Device_Emulator.JIT.Test.csproj | 3 +-
...roid.Device_Emulator.NativeAOT.Test.csproj | 24 +
.../Device_Emulator/NativeAOT/Program.cs | 16 +
15 files changed, 575 insertions(+), 72 deletions(-)
create mode 100755 RunMyTest.sh
create mode 100644 src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
create mode 100644 src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
create mode 100644 src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
diff --git a/RunMyTest.sh b/RunMyTest.sh
new file mode 100755
index 00000000000000..3e396bd5547f19
--- /dev/null
+++ b/RunMyTest.sh
@@ -0,0 +1,3 @@
+./dotnet.sh build src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj
+# ./dotnet.sh build -c Debug src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj /p:RuntimeIdentifier=android-x64 /t:Test /p:RuntimeFlavor=nativeaot -bl /p:targetos=android /p:targetarchitecture=x64 --self-contained /p:_RuntimeIdentifierUsesAppHost=false /p:StripSymbols=false /p:CrossCompileRid=linux-bionic-x64
+./dotnet.sh build -c Debug src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj /p:RuntimeIdentifier=android-x64 /t:Test /p:RuntimeFlavor=nativeaot -bl /p:targetos=android /p:targetarchitecture=x64 --self-contained /p:_RuntimeIdentifierUsesAppHost=false /p:StripSymbols=false /p:CrossCompileRid=linux-bionic-x64
\ No newline at end of file
diff --git a/eng/Subsets.props b/eng/Subsets.props
index 3c854690a1c0a9..cfb99c5db491c4 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -47,7 +47,7 @@
true
- <_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true
+ <_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd' or '$(TargetOS)' == 'android' or '$(TargetOS)' == 'linux-bionic'">true
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'loongarch64' or '$(TargetArchitecture)' == 'riscv64' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true
true
@@ -71,6 +71,7 @@
clr+mono+libs+tools+host+packs
mono+libs+packs
clr+mono+libs+host+packs
+ clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs
clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs
clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+host+packs
clr.nativeaotruntime+clr.nativeaotlibs+libs+packs
@@ -153,7 +154,7 @@
$(BootstrapSubsets)+clr.nativeaotlibs+clr.nativeaotruntime+libs.native
true
-
+
clr.nativeprereqs+clr.iltools+clr.runtime+clr.native+clr.aot+clr.nativeaotlibs+clr.nativeaotruntime+clr.crossarchtools
$(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.packages
diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets
index 15e62c05e04b4e..94f5a67b4eca4f 100644
--- a/eng/targetingpacks.targets
+++ b/eng/targetingpacks.targets
@@ -66,14 +66,14 @@
RuntimeFrameworkName="$(LocalFrameworkOverrideName)"
LatestRuntimeFrameworkVersion="$(ProductVersion)"
RuntimePackNamePatterns="$(LocalFrameworkOverrideName).Runtime.NativeAOT.**RID**"
- RuntimePackRuntimeIdentifiers="ios-arm64;iossimulator-arm64;iossimulator-x64;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;maccatalyst-arm64;maccatalyst-x64;linux-bionic-arm64;linux-bionic-x64;osx-arm64;osx-x64"
+ RuntimePackRuntimeIdentifiers="ios-arm64;iossimulator-arm64;iossimulator-x64;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;maccatalyst-arm64;maccatalyst-x64;linux-bionic-arm64;linux-bionic-x64;android-x64;android-arm64;osx-arm64;osx-x64"
RuntimePackLabels="NativeAOT"
Condition="'$(UseLocalTargetingRuntimePack)' == 'true' and ('@(KnownRuntimePack)' == '' or @(KnownRuntimePack->WithMetadataValue('Identity', 'Microsoft.NETCore.App')->WithMetadataValue('RuntimePackLabels', 'NativeAOT')->WithMetadataValue('TargetFramework', '$(NetCoreAppCurrent)')) == '')" />
$(_originalTargetOS)
<_linuxToken>linux-
<_linuxLibcFlavor Condition="$(_targetOS.StartsWith($(_linuxToken)))">$(_targetOS.SubString($(_linuxToken.Length)))
- <_targetOS Condition="$(_targetOS.StartsWith($(_linuxToken)))">linux
+ <_linuxLibcFlavor Condition="'$(_targetOS)' == 'android'">bionic
+ <_targetOS Condition="$(_targetOS.StartsWith($(_linuxToken))) or $(_targetOS) == 'android'">linux
<_targetArchitectureWithAbi>$(_targetArchitecture)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index b76e5aca25ace1..bf90bc515948b4 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -46,7 +46,7 @@ The .NET Foundation licenses this file to you under the MIT license.
armv7
gnu
- android21
+ android21
musl
gnueabihf
androideabi21
@@ -142,7 +142,8 @@ The .NET Foundation licenses this file to you under the MIT license.
-
+
+
diff --git a/src/coreclr/tools/Common/CommandLineHelpers.cs b/src/coreclr/tools/Common/CommandLineHelpers.cs
index e012abc489be7f..0258f216127054 100644
--- a/src/coreclr/tools/Common/CommandLineHelpers.cs
+++ b/src/coreclr/tools/Common/CommandLineHelpers.cs
@@ -82,6 +82,7 @@ public static TargetOS GetTargetOS(string token)
"ios" => TargetOS.iOS,
"tvossimulator" => TargetOS.tvOSSimulator,
"tvos" => TargetOS.tvOS,
+ "android" => TargetOS.Linux,
_ => throw new CommandLineException($"Target OS '{token}' is not supported")
};
}
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index 7b88d5a39943ac..e756eba33ea81c 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -3,7 +3,7 @@
$(TargetOS)-$(TargetArchitecture.ToLowerInvariant())
- false
+ false
true
true
@@ -14,6 +14,7 @@
<_IsLibraryMode Condition="'$(UseMonoRuntime)' == 'true' and '$(UseNativeAOTRuntime)' != 'true' and '$(NativeLib)' != ''">true
<_ReadRuntimeComponentsManifestTargetName Condition="'$(UseMonoRuntime)' == 'true' and '$(UseNativeAOTRuntime)' != 'true'">_MonoReadAvailableComponentsManifest
+ false
false
Publish
diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets
index 886e99635a34c6..b456e10ef7308d 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.targets
+++ b/src/mono/msbuild/android/build/AndroidBuild.targets
@@ -239,6 +239,7 @@
We are using a private property to determine the target runtime, we should instead unify the resolution with Apple targets instead, (see: https://github.com/dotnet/runtime/issues/111923) -->
<_RuntimeFlavor>Mono
<_RuntimeFlavor Condition="'$(UseMonoRuntime)' == 'false' and '$(UseNativeAOTRuntime)' != 'true'">CoreCLR
+ <_RuntimeFlavor Condition="'$(UseNativeAOTRuntime)' == 'true'">nativeaot
+
+
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index df0772393e73a8..91211c43e65596 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -15,7 +15,8 @@
public enum RuntimeFlavorEnum
{
Mono,
- CoreCLR
+ CoreCLR,
+ NativeAOT
}
public partial class ApkBuilder
@@ -53,6 +54,7 @@ public partial class ApkBuilder
private RuntimeFlavorEnum parsedRuntimeFlavor;
private bool IsMono => parsedRuntimeFlavor == RuntimeFlavorEnum.Mono;
private bool IsCoreCLR => parsedRuntimeFlavor == RuntimeFlavorEnum.CoreCLR;
+ private bool IsNativeAOT => parsedRuntimeFlavor == RuntimeFlavorEnum.NativeAOT;
private TaskLoggingHelper logger;
@@ -91,7 +93,8 @@ public ApkBuilder(TaskLoggingHelper logger)
throw new ArgumentException($"ProjectName='{ProjectName}' should not not contain spaces.");
}
- if (string.IsNullOrEmpty(AndroidSdk)){
+ if (string.IsNullOrEmpty(AndroidSdk))
+ {
AndroidSdk = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT");
}
@@ -154,7 +157,7 @@ public ApkBuilder(TaskLoggingHelper logger)
var assemblerFilesToLink = new StringBuilder();
var aotLibraryFiles = new List();
- if (!IsLibraryMode)
+ if (!(IsLibraryMode || IsNativeAOT))
{
foreach (ITaskItem file in Assemblies)
{
@@ -243,6 +246,10 @@ public ApkBuilder(TaskLoggingHelper logger)
if (IsLibraryMode)
{
nativeLibraries = string.Join("\n ", NativeDependencies.Select(dep => dep));
+ }
+ else if (IsNativeAOT)
+ {
+
}
else
{
@@ -264,7 +271,7 @@ public ApkBuilder(TaskLoggingHelper logger)
runtimeLib = Path.Combine(AppDir, "libcoreclr.so");
}
- if (!File.Exists(runtimeLib))
+ if (!File.Exists(runtimeLib) && !IsNativeAOT)
{
throw new ArgumentException($"{runtimeLib} was not found");
}
@@ -325,72 +332,79 @@ public ApkBuilder(TaskLoggingHelper logger)
nativeLibraries += $" libc++_static.a{Environment.NewLine}";
}
}
-
- StringBuilder extraLinkerArgs = new StringBuilder();
- foreach (ITaskItem item in ExtraLinkerArguments)
+ string abi;
+ if (IsNativeAOT)
{
- extraLinkerArgs.AppendLine($" \"{item.ItemSpec}\"");
+ abi = AndroidProject.DetermineAbi(runtimeIdentifier);
}
-
- if (StaticLinkedRuntime && IsCoreCLR)
+ else
{
- // Ensure global symbol references in the shared library are resolved to definitions in
- // the same shared library. For the static linked runtime specifically, we need this for
- // global functions in assembly for the linker to treat relative offsets to them as constant
- extraLinkerArgs.AppendLine($" \"-Wl,-Bsymbolic\"");
- }
+ StringBuilder extraLinkerArgs = new StringBuilder();
+ foreach (ITaskItem item in ExtraLinkerArguments)
+ {
+ extraLinkerArgs.AppendLine($" \"{item.ItemSpec}\"");
+ }
- nativeLibraries += assemblerFilesToLink.ToString();
+ if (StaticLinkedRuntime && IsCoreCLR)
+ {
+ // Ensure global symbol references in the shared library are resolved to definitions in
+ // the same shared library. For the static linked runtime specifically, we need this for
+ // global functions in assembly for the linker to treat relative offsets to them as constant
+ extraLinkerArgs.AppendLine($" \"-Wl,-Bsymbolic\"");
+ }
- string aotSources = assemblerFiles.ToString();
- string monodroidSource = IsCoreCLR ?
- "monodroid-coreclr.c" : (IsLibraryMode) ? "monodroid-librarymode.c" : "monodroid.c";
- string runtimeInclude = string.Join(" ", runtimeHeaders.Select(h => $"\"{NormalizePathToUnix(h)}\""));
+ nativeLibraries += assemblerFilesToLink.ToString();
- string cmakeLists = Utils.GetEmbeddedResource("CMakeLists-android.txt")
- .Replace("%RuntimeInclude%", runtimeInclude)
- .Replace("%NativeLibrariesToLink%", NormalizePathToUnix(nativeLibraries))
- .Replace("%MONODROID_SOURCE%", monodroidSource)
- .Replace("%AotSources%", NormalizePathToUnix(aotSources))
- .Replace("%AotModulesSource%", string.IsNullOrEmpty(aotSources) ? "" : "modules.c")
- .Replace("%APP_LINKER_ARGS%", extraLinkerArgs.ToString());
+ string aotSources = assemblerFiles.ToString();
+ string monodroidSource = IsCoreCLR ?
+ "monodroid-coreclr.c" : (IsLibraryMode) ? "monodroid-librarymode.c" : "monodroid.c";
+ string runtimeInclude = string.Join(" ", runtimeHeaders.Select(h => $"\"{NormalizePathToUnix(h)}\""));
- var defines = new StringBuilder();
- if (ForceInterpreter)
- {
- defines.AppendLine("add_definitions(-DFORCE_INTERPRETER=1)");
- }
- else if (ForceAOT)
- {
- defines.AppendLine("add_definitions(-DFORCE_AOT=1)");
- if (aotLibraryFiles.Count == 0)
+ string cmakeLists = Utils.GetEmbeddedResource("CMakeLists-android.txt")
+ .Replace("%RuntimeInclude%", runtimeInclude)
+ .Replace("%NativeLibrariesToLink%", NormalizePathToUnix(nativeLibraries))
+ .Replace("%MONODROID_SOURCE%", monodroidSource)
+ .Replace("%AotSources%", NormalizePathToUnix(aotSources))
+ .Replace("%AotModulesSource%", string.IsNullOrEmpty(aotSources) ? "" : "modules.c")
+ .Replace("%APP_LINKER_ARGS%", extraLinkerArgs.ToString());
+
+ var defines = new StringBuilder();
+ if (ForceInterpreter)
{
- defines.AppendLine("add_definitions(-DSTATIC_AOT=1)");
+ defines.AppendLine("add_definitions(-DFORCE_INTERPRETER=1)");
+ }
+ else if (ForceAOT)
+ {
+ defines.AppendLine("add_definitions(-DFORCE_AOT=1)");
+ if (aotLibraryFiles.Count == 0)
+ {
+ defines.AppendLine("add_definitions(-DSTATIC_AOT=1)");
+ }
}
- }
- if (ForceFullAOT)
- {
- defines.AppendLine("add_definitions(-DFULL_AOT=1)");
- }
+ if (ForceFullAOT)
+ {
+ defines.AppendLine("add_definitions(-DFULL_AOT=1)");
+ }
- if (!string.IsNullOrEmpty(DiagnosticPorts))
- {
- defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
- }
+ if (!string.IsNullOrEmpty(DiagnosticPorts))
+ {
+ defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
+ }
- cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
+ cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
- File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);
- File.WriteAllText(Path.Combine(OutputDir, monodroidSource), Utils.GetEmbeddedResource(monodroidSource));
+ File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);
+ File.WriteAllText(Path.Combine(OutputDir, monodroidSource), Utils.GetEmbeddedResource(monodroidSource));
- AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger);
- project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols);
- project.BuildCMake(OutputDir, StripDebugSymbols);
+ AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger);
+ project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols);
+ project.BuildCMake(OutputDir, StripDebugSymbols);
- // TODO: https://github.com/dotnet/runtime/issues/115717
+ // TODO: https://github.com/dotnet/runtime/issues/115717
- string abi = project.Abi;
+ abi = project.Abi;
+ }
// 2. Compile Java files
@@ -429,11 +443,22 @@ public ApkBuilder(TaskLoggingHelper logger)
envVariables += $"\t\tsetEnv(\"DOTNET_SYSTEM_GLOBALIZATION_INVARIANT\", \"true\");\n";
}
- string jniLibraryName = (IsLibraryMode) ? ProjectName! :
- (StaticLinkedRuntime && IsCoreCLR) ? "monodroid" : "System.Security.Cryptography.Native.Android";
+ string jniLibraryName;
+ if (IsLibraryMode || IsNativeAOT)
+ jniLibraryName = ProjectName!;
+ else if (StaticLinkedRuntime && IsCoreCLR)
+ jniLibraryName = "monodroid";
+ else
+ jniLibraryName = "System.Security.Cryptography.Native.Android";
+
+ List librariesToLoad = [jniLibraryName];
+ if (!IsNativeAOT)
+ librariesToLoad.Add("monodroid");
+
string monoRunner = Utils.GetEmbeddedResource("MonoRunner.java")
.Replace("%EntryPointLibName%", Path.GetFileName(mainLibraryFileName))
- .Replace("%JNI_LIBRARY_NAME%", jniLibraryName)
+ .Replace("%LoadLibraryStatements%",
+ string.Join('\n', librariesToLoad.Select(l => $"System.loadLibrary(\"{l}\");")))
.Replace("%EnvVariables%", envVariables);
File.WriteAllText(monoRunnerPath, monoRunner);
@@ -454,8 +479,13 @@ public ApkBuilder(TaskLoggingHelper logger)
if (classFiles.Length == 0)
throw new InvalidOperationException("Didn't find any .class files");
+ List inputFiles = [.. classFiles];
+ if (IsNativeAOT)
+ {
+ inputFiles.Add(Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(AppDir)!)!, "libSystem.Security.Cryptography.Native.Android.jar"));
+ }
- Utils.RunProcess(logger, androidSdkHelper.D8Path, $"--no-desugaring {string.Join(" ", classFiles)}", workingDir: OutputDir);
+ Utils.RunProcess(logger, androidSdkHelper.D8Path, $"--no-desugaring {string.Join(" ", inputFiles)}", workingDir: OutputDir);
}
else
{
@@ -469,7 +499,8 @@ public ApkBuilder(TaskLoggingHelper logger)
Utils.RunProcess(logger, androidSdkHelper.AaptPath, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir);
var dynamicLibs = new List();
- dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so"));
+ if (!IsNativeAOT)
+ dynamicLibs.Add(Path.Combine(AppDir, mainLibraryFileName));
if (IsLibraryMode)
{
@@ -532,7 +563,6 @@ public ApkBuilder(TaskLoggingHelper logger)
}
// NOTE: we can run android-strip tool from NDK to shrink native binaries here even more.
-
File.Copy(dynamicLib, Path.Combine(OutputDir, destRelative), true);
Utils.RunProcess(logger, androidSdkHelper.AaptPath, $"add {apkFile} {NormalizePathToUnix(destRelative)}", workingDir: OutputDir);
}
diff --git a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
index f8938e9fff316c..c384a85066804b 100644
--- a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
+++ b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
@@ -34,8 +34,7 @@ public class MonoRunner extends Instrumentation
{
static {
// loadLibrary triggers JNI_OnLoad in these libs
- System.loadLibrary("%JNI_LIBRARY_NAME%");
- System.loadLibrary("monodroid");
+ %LoadLibraryStatements%
}
static String testResultsDir;
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
new file mode 100644
index 00000000000000..755963ad342df0
--- /dev/null
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -0,0 +1,422 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.InteropServices;
+using System.Runtime;
+using System;
+using System.Runtime.CompilerServices;
+
+using JObject = nint;
+using JString = nint;
+using JObjectArray = nint;
+
+namespace MonoDroid.NativeAOT;
+
+#pragma warning disable IDE0060 // Remove unused parameter
+internal static unsafe partial class MonoDroidExports
+{
+ // void Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstring j_value);
+ [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_setEnv")]
+ public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_value)
+ {
+ string key = env->GetStringUTFChars(j_key);
+ string value = env->GetStringUTFChars(j_value);
+ Environment.SetEnvironmentVariable(key, value);
+ }
+
+ // int Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_entryPointLibName, long current_local_time);
+ [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_initRuntime")]
+ public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JString j_entryPointLibName, long current_local_time)
+ {
+ // The NativeAOT runtime does not need to be initialized, but the crypto library does.
+ JavaVM* javaVM = env->GetJavaVM();
+ AndroidCryptoNative_InitLibraryOnLoad(javaVM, null);
+ return 0;
+ }
+
+ [LibraryImport("System.Security.Cryptography.Native.Android")]
+ internal static partial int AndroidCryptoNative_InitLibraryOnLoad(JavaVM* vm, void* reserved);
+
+ // int Java_net_dot_MonoRunner_execEntryPoint (JNIEnv* env, jobject thiz, jstring j_entryPointLibName, jobjectArray j_args);
+ [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_execEntryPoint")]
+ public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPointLibName, JObjectArray j_args)
+ {
+ return Program.Main();
+ }
+
+ // void Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
+ [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_freeNativeResources")]
+ public static void FreeNativeResources(JNIEnv* env, JObject thiz)
+ {
+ // Placeholder for actual implementation
+ Console.WriteLine("FreeNativeResources start");
+ }
+}
+
+
+[StructLayout(LayoutKind.Sequential)]
+internal unsafe struct JNIEnv
+{
+ JNINativeInterface* NativeInterface;
+ public string GetStringUTFChars(JString str)
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ byte* chars = NativeInterface->GetStringUTFChars(thisptr, str, out byte isCopy);
+ string result = Marshal.PtrToStringUTF8((nint)chars);
+ if (isCopy != 0)
+ NativeInterface->ReleaseStringUTFChars(thisptr, str, chars);
+ return result;
+ }
+ }
+
+ public JavaVM* GetJavaVM()
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ JavaVM* vm;
+ NativeInterface->GetJavaVM(thisptr, &vm);
+ return vm;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ unsafe struct JNINativeInterface
+ {
+ void* reserved0;
+ void* reserved1;
+ void* reserved2;
+
+ void* reserved3;
+ void* GetVersion;
+
+ void* DefineClass;
+ void* FindClass;
+
+ void* FromReflectedMethod;
+ void* FromReflectedField;
+
+ void* ToReflectedMethod;
+
+ void* GetSuperclass;
+ void* IsAssignableFrom;
+
+ void* ToReflectedField;
+
+ void* Throw;
+ void* ThrowNew;
+ void* ExceptionOccurred;
+ void* ExceptionDescribe;
+ void* ExceptionClear;
+ void* FatalError;
+
+ void* PushLocalFrame;
+ void* PopLocalFrame;
+
+ void* NewGlobalRef;
+ void* DeleteGlobalRef;
+ void* DeleteLocalRef;
+ void* IsSameObject;
+ void* NewLocalRef;
+ void* EnsureLocalCapacity;
+
+ void* AllocObject;
+ void* NewObject;
+ void* NewObjectV;
+ void* NewObjectA;
+
+ void* GetObjectClass;
+ void* IsInstanceOf;
+
+ void* GetMethodID;
+
+ void* CallObjectMethod;
+ void* CallObjectMethodV;
+ void* CallObjectMethodA;
+
+ void* CallBooleanMethod;
+ void* CallBooleanMethodV;
+ void* CallBooleanMethodA;
+
+ void* CallByteMethod;
+ void* CallByteMethodV;
+ void* CallByteMethodA;
+
+ void* CallCharMethod;
+ void* CallCharMethodV;
+ void* CallCharMethodA;
+
+ void* CallShortMethod;
+ void* CallShortMethodV;
+ void* CallShortMethodA;
+
+ void* CallIntMethod;
+ void* CallIntMethodV;
+ void* CallIntMethodA;
+
+ void* CallLongMethod;
+ void* CallLongMethodV;
+ void* CallLongMethodA;
+
+ void* CallFloatMethod;
+ void* CallFloatMethodV;
+ void* CallFloatMethodA;
+
+ void* CallDoubleMethod;
+ void* CallDoubleMethodV;
+ void* CallDoubleMethodA;
+
+ void* CallVoidMethod;
+ void* CallVoidMethodV;
+ void* CallVoidMethodA;
+
+ void* CallNonvirtualObjectMethod;
+ void* CallNonvirtualObjectMethodV;
+ void* CallNonvirtualObjectMethodA;
+
+ void* CallNonvirtualBooleanMethod;
+ void* CallNonvirtualBooleanMethodV;
+ void* CallNonvirtualBooleanMethodA;
+
+ void* CallNonvirtualByteMethod;
+ void* CallNonvirtualByteMethodV;
+ void* CallNonvirtualByteMethodA;
+
+ void* CallNonvirtualCharMethod;
+ void* CallNonvirtualCharMethodV;
+ void* CallNonvirtualCharMethodA;
+
+ void* CallNonvirtualShortMethod;
+ void* CallNonvirtualShortMethodV;
+ void* CallNonvirtualShortMethodA;
+
+ void* CallNonvirtualIntMethod;
+ void* CallNonvirtualIntMethodV;
+ void* CallNonvirtualIntMethodA;
+
+ void* CallNonvirtualLongMethod;
+ void* CallNonvirtualLongMethodV;
+ void* CallNonvirtualLongMethodA;
+
+ void* CallNonvirtualFloatMethod;
+ void* CallNonvirtualFloatMethodV;
+ void* CallNonvirtualFloatMethodA;
+
+ void* CallNonvirtualDoubleMethod;
+ void* CallNonvirtualDoubleMethodV;
+ void* CallNonvirtualDoubleMethodA;
+
+ void* CallNonvirtualVoidMethod;
+ void* CallNonvirtualVoidMethodV;
+ void* CallNonvirtualVoidMethodA;
+
+ void* GetFieldID;
+
+ void* GetObjectField;
+ void* GetBooleanField;
+ void* GetByteField;
+ void* GetCharField;
+ void* GetShortField;
+ void* GetIntField;
+ void* GetLongField;
+ void* GetFloatField;
+ void* GetDoubleField;
+
+ void* SetObjectField;
+ void* SetBooleanField;
+ void* SetByteField;
+ void* SetCharField;
+ void* SetShortField;
+ void* SetIntField;
+ void* SetLongField;
+ void* SetFloatField;
+ void* SetDoubleField;
+
+ void* GetStaticMethodID;
+
+ void* CallStaticObjectMethod;
+ void* CallStaticObjectMethodV;
+ void* CallStaticObjectMethodA;
+
+ void* CallStaticBooleanMethod;
+ void* CallStaticBooleanMethodV;
+ void* CallStaticBooleanMethodA;
+
+ void* CallStaticByteMethod;
+ void* CallStaticByteMethodV;
+ void* CallStaticByteMethodA;
+
+ void* CallStaticCharMethod;
+ void* CallStaticCharMethodV;
+ void* CallStaticCharMethodA;
+
+ void* CallStaticShortMethod;
+ void* CallStaticShortMethodV;
+ void* CallStaticShortMethodA;
+
+ void* CallStaticIntMethod;
+ void* CallStaticIntMethodV;
+ void* CallStaticIntMethodA;
+
+ void* CallStaticLongMethod;
+ void* CallStaticLongMethodV;
+ void* CallStaticLongMethodA;
+
+ void* CallStaticFloatMethod;
+ void* CallStaticFloatMethodV;
+ void* CallStaticFloatMethodA;
+
+ void* CallStaticDoubleMethod;
+ void* CallStaticDoubleMethodV;
+ void* CallStaticDoubleMethodA;
+
+ void* CallStaticVoidMethod;
+ void* CallStaticVoidMethodV;
+ void* CallStaticVoidMethodA;
+
+ void* GetStaticFieldID;
+ void* GetStaticObjectField;
+ void* GetStaticBooleanField;
+ void* GetStaticByteField;
+ void* GetStaticCharField;
+ void* GetStaticShortField;
+ void* GetStaticIntField;
+ void* GetStaticLongField;
+ void* GetStaticFloatField;
+ void* GetStaticDoubleField;
+
+ void* SetStaticObjectField;
+ void* SetStaticBooleanField;
+ void* SetStaticByteField;
+ void* SetStaticCharField;
+ void* SetStaticShortField;
+ void* SetStaticIntField;
+ void* SetStaticLongField;
+ void* SetStaticFloatField;
+ void* SetStaticDoubleField;
+
+ void* NewString;
+ void* GetStringLength;
+ void* GetStringChars;
+ void* ReleaseStringChars;
+
+ void* NewStringUTF;
+ delegate* unmanaged[Cdecl] GetStringUTFLength;
+ public delegate* unmanaged[Cdecl] GetStringUTFChars;
+ public delegate* unmanaged[Cdecl] ReleaseStringUTFChars;
+
+ void* GetArrayLength;
+
+ void* NewObjectArray;
+ void* GetObjectArrayElement;
+ void* SetObjectArrayElement;
+
+ void* NewBooleanArray;
+ void* NewByteArray;
+ void* NewCharArray;
+ void* NewShortArray;
+ void* NewIntArray;
+ void* NewLongArray;
+ void* NewFloatArray;
+ void* NewDoubleArray;
+
+ void* GetBooleanArrayElements;
+ void* GetByteArrayElements;
+ void* GetCharArrayElements;
+ void* GetShortArrayElements;
+ void* GetIntArrayElements;
+ void* GetLongArrayElements;
+ void* GetFloatArrayElements;
+ void* GetDoubleArrayElements;
+
+ void* ReleaseBooleanArrayElements;
+ void* ReleaseByteArrayElements;
+ void* ReleaseCharArrayElements;
+ void* ReleaseShortArrayElements;
+ void* ReleaseIntArrayElements;
+ void* ReleaseLongArrayElements;
+ void* ReleaseFloatArrayElements;
+ void* ReleaseDoubleArrayElements;
+
+ void* GetBooleanArrayRegion;
+ void* GetByteArrayRegion;
+ void* GetCharArrayRegion;
+ void* GetShortArrayRegion;
+ void* GetIntArrayRegion;
+ void* GetLongArrayRegion;
+ void* GetFloatArrayRegion;
+ void* GetDoubleArrayRegion;
+
+ void* SetBooleanArrayRegion;
+ void* SetByteArrayRegion;
+ void* SetCharArrayRegion;
+ void* SetShortArrayRegion;
+ void* SetIntArrayRegion;
+ void* SetLongArrayRegion;
+ void* SetFloatArrayRegion;
+ void* SetDoubleArrayRegion;
+
+ void* RegisterNatives;
+ void* UnregisterNatives;
+
+ void* MonitorEnter;
+ void* MonitorExit;
+
+ public delegate* unmanaged[Cdecl] GetJavaVM;
+
+ void* GetStringRegion;
+ void* GetStringUTFRegion;
+
+ void* GetPrimitiveArrayCritical;
+ void* ReleasePrimitiveArrayCritical;
+
+ void* GetStringCritical;
+ void* ReleaseStringCritical;
+
+ void* NewWeakGlobalRef;
+ void* DeleteWeakGlobalRef;
+
+ void* ExceptionCheck;
+
+ void* NewDirectByteBuffer;
+ void* GetDirectBufferAddress;
+ void* GetDirectBufferCapacity;
+
+ /* New JNI 1.6 Features */
+
+ void* GetObjectRefType;
+
+ /* Module Features */
+
+ void* GetModule;
+
+ /* Virtual threads */
+
+ void* IsVirtualThread;
+
+ /* Large UTF8 Support */
+
+ void* GetStringUTFLengthAsLong;
+ };
+}
+
+[StructLayout(LayoutKind.Sequential)]
+internal unsafe struct JavaVM
+{
+ JNIInvokeInterface* InvokeInterface;
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct JNIInvokeInterface
+ {
+ void* reserved0;
+ void* reserved1;
+ void* reserved2;
+ void* DestroyJavaVM;
+ void* AttachCurrentThread;
+ void* DetachCurrentThread;
+ void* GetEnv;
+ void* AttachCurrentThreadAsDaemon;
+ }
+}
+
+#pragma warning restore IDE0060 // Remove unused parameter
diff --git a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
index b482731671ac22..b3c3ab55ba85da 100644
--- a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
+++ b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
@@ -151,7 +151,7 @@ private static string GetHostOS()
return "linux";
}
- private static string DetermineAbi(string runtimeIdentifier) =>
+ public static string DetermineAbi(string runtimeIdentifier) =>
runtimeIdentifier switch
{
"android-x86" => "x86",
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
index 47cc5e4e1e6496..235ada2c3d5832 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
@@ -6,9 +6,10 @@
$(NetCoreAppCurrent)
Android.Device_Emulator.JIT.Test.dll
42
+ true
-
\ No newline at end of file
+
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
new file mode 100644
index 00000000000000..15886021dd3d62
--- /dev/null
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
@@ -0,0 +1,24 @@
+
+
+
+ Library
+ true
+ $(NetCoreAppCurrent)
+ lib$(MSBuildProjectName)
+ $(TargetName).so
+ 42
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
new file mode 100644
index 00000000000000..f8430023829079
--- /dev/null
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+public class Program
+{
+ public static int Main()
+ {
+ string message = "Hello, Android!";
+ Console.WriteLine(message); // logcat
+ // Test the linux-bionic cryptography library
+ Console.WriteLine(System.Security.Cryptography.SHA256.HashData(new byte[] {0x1, 0x2, 0x3}));
+ return 42;
+ }
+}
\ No newline at end of file
From a3d30c1a8dd9b1ffb3b7dc0f3eeabe01fd08987a Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 24 Jul 2025 22:05:38 +0000
Subject: [PATCH 02/33] Undo extra changes, add reference in tests.proj
---
RunMyTest.sh | 3 ---
src/libraries/tests.proj | 5 +++++
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 2 +-
.../JIT/Android.Device_Emulator.JIT.Test.csproj | 3 +--
4 files changed, 7 insertions(+), 6 deletions(-)
delete mode 100755 RunMyTest.sh
diff --git a/RunMyTest.sh b/RunMyTest.sh
deleted file mode 100755
index 3e396bd5547f19..00000000000000
--- a/RunMyTest.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-./dotnet.sh build src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj
-# ./dotnet.sh build -c Debug src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj /p:RuntimeIdentifier=android-x64 /t:Test /p:RuntimeFlavor=nativeaot -bl /p:targetos=android /p:targetarchitecture=x64 --self-contained /p:_RuntimeIdentifierUsesAppHost=false /p:StripSymbols=false /p:CrossCompileRid=linux-bionic-x64
-./dotnet.sh build -c Debug src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj /p:RuntimeIdentifier=android-x64 /t:Test /p:RuntimeFlavor=nativeaot -bl /p:targetos=android /p:targetarchitecture=x64 --self-contained /p:_RuntimeIdentifierUsesAppHost=false /p:StripSymbols=false /p:CrossCompileRid=linux-bionic-x64
\ No newline at end of file
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index ef18f05dac4f61..44aaf6bd342152 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -721,6 +721,11 @@
BuildInParallel="false" />
+
+
+
+
false
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 91211c43e65596..74c77d0d48f911 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -500,7 +500,7 @@ public ApkBuilder(TaskLoggingHelper logger)
var dynamicLibs = new List();
if (!IsNativeAOT)
- dynamicLibs.Add(Path.Combine(AppDir, mainLibraryFileName));
+ dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so"));
if (IsLibraryMode)
{
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
index 235ada2c3d5832..47cc5e4e1e6496 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj
@@ -6,10 +6,9 @@
$(NetCoreAppCurrent)
Android.Device_Emulator.JIT.Test.dll
42
- true
-
+
\ No newline at end of file
From ae6a9ce7d31d0e2cc2b2ca0e42ec7aa8add4e13f Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 24 Jul 2025 22:09:16 +0000
Subject: [PATCH 03/33] Remove emtpy 'if' case
---
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 74c77d0d48f911..bb6f7644fbf77d 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -247,11 +247,7 @@ public ApkBuilder(TaskLoggingHelper logger)
{
nativeLibraries = string.Join("\n ", NativeDependencies.Select(dep => dep));
}
- else if (IsNativeAOT)
- {
-
- }
- else
+ else if (!IsNativeAOT)
{
string runtimeLib = "";
if (StaticLinkedRuntime && IsMono)
From 68b972a6f5c23d03d497ec69a6e69b12cc4f675d Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 24 Jul 2025 23:47:03 +0000
Subject: [PATCH 04/33] Remove extra android->linux translations
---
.../Microsoft.DotNet.ILCompiler.SingleEntry.targets | 1 -
src/coreclr/tools/Common/CommandLineHelpers.cs | 1 -
2 files changed, 2 deletions(-)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
index c4bb204920b443..8521b0f972fe16 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
@@ -32,7 +32,6 @@
<_linuxToken>linux-
<_linuxLibcFlavor Condition="$(_targetOS.StartsWith($(_linuxToken)))">$(_targetOS.SubString($(_linuxToken.Length)))
<_linuxLibcFlavor Condition="'$(_targetOS)' == 'android'">bionic
- <_targetOS Condition="$(_targetOS.StartsWith($(_linuxToken))) or $(_targetOS) == 'android'">linux
<_targetArchitectureWithAbi>$(_targetArchitecture)
diff --git a/src/coreclr/tools/Common/CommandLineHelpers.cs b/src/coreclr/tools/Common/CommandLineHelpers.cs
index 0258f216127054..e012abc489be7f 100644
--- a/src/coreclr/tools/Common/CommandLineHelpers.cs
+++ b/src/coreclr/tools/Common/CommandLineHelpers.cs
@@ -82,7 +82,6 @@ public static TargetOS GetTargetOS(string token)
"ios" => TargetOS.iOS,
"tvossimulator" => TargetOS.tvOSSimulator,
"tvos" => TargetOS.tvOS,
- "android" => TargetOS.Linux,
_ => throw new CommandLineException($"Target OS '{token}' is not supported")
};
}
From 044b176fad9068e334961d4e5157667f3aeecc29 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Fri, 25 Jul 2025 16:23:09 +0000
Subject: [PATCH 05/33] Remove redundant IsNativeAOT check
---
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 8fdc7717b19ad6..0c96599beb09d8 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -266,7 +266,7 @@ public ApkBuilder(TaskLoggingHelper logger)
runtimeLib = Path.Combine(AppDir, "libcoreclr.so");
}
- if (!File.Exists(runtimeLib) && !IsNativeAOT)
+ if (!File.Exists(runtimeLib))
{
throw new ArgumentException($"{runtimeLib} was not found");
}
From d74d3ecad04a30ffa3fbecc00803fc3ba87de556 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 18:04:39 +0000
Subject: [PATCH 06/33] Fix build to work in CI
- 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)
---
eng/pipelines/runtime.yml | 42 +++++++++++++++++++
eng/testing/tests.android.targets | 1 -
eng/testing/tests.singlefile.targets | 5 ++-
src/libraries/tests.proj | 11 +++--
.../android/build/AndroidBuild.targets | 1 -
5 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index e213156d849e5f..2fcb00480b59a8 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -993,6 +993,48 @@ extends:
eq(variables['coreclrContainsChange'], true),
eq(variables['isRollingBuild'], true))
+ #
+ # Android arm64 devices and x64 emulators
+ # Build the whole product using CoreCLR and run functional tests
+ #
+ - template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: nativeaot
+ platforms:
+ - android_x64
+ - android_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: coreclrContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: NativeAOT
+ buildArgs: -s clr.aot+libs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true
+ timeoutInMinutes: 120
+ condition: >-
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isRollingBuild'], true))
+ # extra steps, run tests
+ postBuildSteps:
+ - template: /eng/pipelines/libraries/helix.yml
+ parameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['coreclrContainsChange'], true),
+ eq(variables['isRollingBuild'], true))
+
#
# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
# Build the whole product using Mono and run libraries tests
diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index 4144799c78f908..5bcd9d4bc63d2e 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -28,7 +28,6 @@
AndroidTestRunner.dll
$(PublishDir)
- $(BundleDir)
diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets
index fab26560f4b61f..13384fa0550b17 100644
--- a/eng/testing/tests.singlefile.targets
+++ b/eng/testing/tests.singlefile.targets
@@ -1,6 +1,6 @@
- Exe
+ Exe
$([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish'))
$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))
@@ -49,7 +49,8 @@
+ Link="Common\SingleFileTestRunner\SingleFileTestRunner.cs"
+ Condition="'$(IsFunctionalTest)' != 'true'" />
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index b4dea5bd5cef4a..9f74b78e9ecc3e 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -574,7 +574,7 @@
-
+
@@ -607,6 +607,10 @@
+
+
+
+
diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets
index 62042a900369a5..3604334079758c 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.targets
+++ b/src/mono/msbuild/android/build/AndroidBuild.targets
@@ -292,5 +292,4 @@
-
From 87a4ccab3deb4e21f36ebb9fd9a6a4a942f6b92c Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 18:31:52 +0000
Subject: [PATCH 07/33] Fix apkbuilder.cs errors after merge
---
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 40 +++++------------------
1 file changed, 8 insertions(+), 32 deletions(-)
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 26108a3f94c32f..4e5f870443287f 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -391,45 +391,21 @@ public ApkBuilder(TaskLoggingHelper logger)
cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);
- File.WriteAllText(Path.Combine(OutputDir, monodroidSource), Utils.GetEmbeddedResource(monodroidSource));
+
+ string monodroidContent = Utils.GetEmbeddedResource(monodroidSource);
+ if (IsCoreCLR)
+ {
+ monodroidContent = RenderMonodroidCoreClrTemplate(monodroidContent);
+ }
+ File.WriteAllText(Path.Combine(OutputDir, monodroidSource), monodroidContent);
AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger);
project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols);
project.BuildCMake(OutputDir, StripDebugSymbols);
-
- // TODO: https://github.com/dotnet/runtime/issues/115717
-
abi = project.Abi;
- }
-
- if (ForceFullAOT)
- {
- defines.AppendLine("add_definitions(-DFULL_AOT=1)");
- }
- if (!string.IsNullOrEmpty(DiagnosticPorts))
- {
- defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
- }
-
- cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
-
- File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);
-
- string monodroidContent = Utils.GetEmbeddedResource(monodroidSource);
- if (IsCoreCLR)
- {
- monodroidContent = RenderMonodroidCoreClrTemplate(monodroidContent);
+ // TODO: https://github.com/dotnet/runtime/issues/115717
}
- File.WriteAllText(Path.Combine(OutputDir, monodroidSource), monodroidContent);
-
- AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger);
- project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols);
- project.BuildCMake(OutputDir, StripDebugSymbols);
-
- // TODO: https://github.com/dotnet/runtime/issues/115717
-
- string abi = project.Abi;
// 2. Compile Java files
From 8de0a5743605634079c6a30f265cbd63e2179730 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 19:27:14 +0000
Subject: [PATCH 08/33] Undo deleted line in ILC.targets, build libs.tests in
pipeline
---
eng/pipelines/runtime.yml | 2 +-
.../Microsoft.DotNet.ILCompiler.SingleEntry.targets | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 68b5647887b6cd..cec952f70b8292 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -1015,7 +1015,7 @@ extends:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true
timeoutInMinutes: 120
condition: >-
or(
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
index 8521b0f972fe16..cf313984696b5f 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets
@@ -32,6 +32,7 @@
<_linuxToken>linux-
<_linuxLibcFlavor Condition="$(_targetOS.StartsWith($(_linuxToken)))">$(_targetOS.SubString($(_linuxToken.Length)))
<_linuxLibcFlavor Condition="'$(_targetOS)' == 'android'">bionic
+ <_targetOS Condition="$(_targetOS.StartsWith($(_linuxToken)))">linux
<_targetArchitectureWithAbi>$(_targetArchitecture)
From 36dfe6159a21fc2cfa944c6ca58b1d0f962d5d03 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 20:51:18 +0000
Subject: [PATCH 09/33] Add missing args to build command
---
eng/pipelines/runtime.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index cec952f70b8292..70953c6d8d8c98 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -1015,7 +1015,7 @@ extends:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
timeoutInMinutes: 120
condition: >-
or(
From 152ec038d711e06a1989f141932257c2c737eb01 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 22:34:14 +0000
Subject: [PATCH 10/33] Set CppCompilerAndLinker to NDK clang when targeting
android
---
src/mono/msbuild/android/build/AndroidBuild.props | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index e756eba33ea81c..0499c7cb0d21fc 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -17,6 +17,12 @@
false
false
+
+ linux-x86_64
+ darwin-x86_64
+ windows-x86_64
+ $(ANDROID_NDK_ROOT)\toolchains\llvm\prebuilt\$(NdkToolchainPrebuiltOS)\bin\clang
+
Publish
$(_ReadRuntimeComponentsManifestTargetName);
From 0facf06f9658d8f92fde58f4012f655f7bd6e45a Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 28 Jul 2025 23:00:22 +0000
Subject: [PATCH 11/33] Ensure Android build runs after CopyNativeBinary
---
src/mono/msbuild/android/build/AndroidBuild.props | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index 0499c7cb0d21fc..c5a1d39045cdfd 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -42,6 +42,11 @@
_AndroidGenerateAppBundle;
_AfterAndroidBuild
+
+ $(AndroidBuildDependsOn);
+ CopyNativeBinary;
+ _CopyAotSymbols
+
<_CommonTargetsDir Condition="'$(_CommonTargetsDir)' == ''">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', '..', 'common'))
From 5e7feaaca1f7821d46aa4a4ef387d44e08605e12 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 30 Jul 2025 15:47:14 +0000
Subject: [PATCH 12/33] Test CI in Debug config
---
eng/pipelines/runtime.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 70953c6d8d8c98..de3832be5d8394 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -1001,7 +1001,7 @@ extends:
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Release
+ buildConfig: Debug
runtimeFlavor: nativeaot
platforms:
- android_x64
@@ -1027,6 +1027,8 @@ extends:
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
parameters:
+ targetRid: android-x64
+ runtimeFlavor: coreclr
creator: dotnet-bot
testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
condition: >-
From 3c86a914c20bf399a6e87c43ab654fae9fb68d75 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 30 Jul 2025 18:30:36 +0000
Subject: [PATCH 13/33] Move leg to runtime-extra-platforms
---
.../runtime-extra-platforms-android.yml | 44 +++++++++++++++++++
eng/pipelines/runtime.yml | 44 +++++++++++++++++++
2 files changed, 88 insertions(+)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
index fa627d38ddda24..23af7ab73fe984 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
@@ -114,3 +114,47 @@ jobs:
parameters:
creator: dotnet-bot
testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig)
+
+#
+# Android arm64 devices and x64 emulators
+# Build the whole product using CoreCLR and run functional tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Debug
+ runtimeFlavor: nativeaot
+ platforms:
+ - android_x64
+ - android_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: coreclrContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: NativeAOT
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
+ timeoutInMinutes: 120
+ condition: >-
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isRollingBuild'], true))
+ # extra steps, run tests
+ postBuildSteps:
+ - template: /eng/pipelines/libraries/helix.yml
+ parameters:
+ targetRid: android-x64
+ runtimeFlavor: coreclr
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['coreclrContainsChange'], true),
+ eq(variables['isRollingBuild'], true))
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index de3832be5d8394..2286d60116c0ec 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -1037,6 +1037,50 @@ extends:
eq(variables['coreclrContainsChange'], true),
eq(variables['isRollingBuild'], true))
+ #
+ # Android arm64 devices and x64 emulators
+ # Build the whole product using CoreCLR and run functional tests
+ #
+ - template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Debug
+ runtimeFlavor: nativeaot
+ platforms:
+ - android_x64
+ - android_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: coreclrContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: NativeAOT
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
+ timeoutInMinutes: 120
+ condition: >-
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isRollingBuild'], true))
+ # extra steps, run tests
+ postBuildSteps:
+ - template: /eng/pipelines/libraries/helix.yml
+ parameters:
+ targetRid: android-x64
+ runtimeFlavor: coreclr
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['coreclrContainsChange'], true),
+ eq(variables['isRollingBuild'], true))
+
#
# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
# Build the whole product using Mono and run libraries tests
From 05deb8f7c854d0b9711e998b8e05f81a58a6213b Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 30 Jul 2025 20:17:48 +0000
Subject: [PATCH 14/33] Remove jobs from runtime
---
.../runtime-extra-platforms-android.yml | 2 -
eng/pipelines/runtime.yml | 88 -------------------
2 files changed, 90 deletions(-)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
index 23af7ab73fe984..a9a350f4cb0446 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
@@ -149,8 +149,6 @@ jobs:
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
parameters:
- targetRid: android-x64
- runtimeFlavor: coreclr
creator: dotnet-bot
testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
condition: >-
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 2286d60116c0ec..8e8817c210449c 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -993,94 +993,6 @@ extends:
eq(variables['coreclrContainsChange'], true),
eq(variables['isRollingBuild'], true))
- #
- # Android arm64 devices and x64 emulators
- # Build the whole product using CoreCLR and run functional tests
- #
- - template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Debug
- runtimeFlavor: nativeaot
- platforms:
- - android_x64
- - android_arm64
- variables:
- # map dependencies variables to local variables
- - name: librariesContainsChange
- value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- - name: coreclrContainsChange
- value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
- jobParameters:
- testGroup: innerloop
- nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
- timeoutInMinutes: 120
- condition: >-
- or(
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- # extra steps, run tests
- postBuildSteps:
- - template: /eng/pipelines/libraries/helix.yml
- parameters:
- targetRid: android-x64
- runtimeFlavor: coreclr
- creator: dotnet-bot
- testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
- condition: >-
- or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['coreclrContainsChange'], true),
- eq(variables['isRollingBuild'], true))
-
- #
- # Android arm64 devices and x64 emulators
- # Build the whole product using CoreCLR and run functional tests
- #
- - template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Debug
- runtimeFlavor: nativeaot
- platforms:
- - android_x64
- - android_arm64
- variables:
- # map dependencies variables to local variables
- - name: librariesContainsChange
- value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- - name: coreclrContainsChange
- value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
- jobParameters:
- testGroup: innerloop
- nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
- timeoutInMinutes: 120
- condition: >-
- or(
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
- eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- # extra steps, run tests
- postBuildSteps:
- - template: /eng/pipelines/libraries/helix.yml
- parameters:
- targetRid: android-x64
- runtimeFlavor: coreclr
- creator: dotnet-bot
- testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
- condition: >-
- or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['coreclrContainsChange'], true),
- eq(variables['isRollingBuild'], true))
-
#
# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
# Build the whole product using Mono and run libraries tests
From 248dddd2e1925dc299052dae529cb551f0b62cdf Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 30 Jul 2025 23:42:58 +0000
Subject: [PATCH 15/33] Exclude nativeaot test on non-nativeaot builds
---
src/libraries/tests.proj | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 1a8531cfc9ed33..57c488e7af842a 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -610,6 +610,9 @@
+
+
+
From 54b995dc2f88bbb86eaa31ac06d896492dfe8ef4 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 31 Jul 2025 17:22:23 +0000
Subject: [PATCH 16/33] Add thread.inl to interoplibinterface_java.cpp to fix
loadLibrary failure
---
src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp b/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp
index 78a65ca93ecd6a..1fcda8be6089d8 100644
--- a/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp
+++ b/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp
@@ -13,6 +13,7 @@
#include "threadstore.h"
#include "threadstore.inl"
#include "event.h"
+#include "thread.inl"
#include "interoplibinterface.h"
From b7e58a1c047946dd04f3621ed0998acebe6827f3 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 31 Jul 2025 17:23:25 +0000
Subject: [PATCH 17/33] Remove android rids from targetpack rids
---
eng/targetingpacks.targets | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets
index 94f5a67b4eca4f..15e62c05e04b4e 100644
--- a/eng/targetingpacks.targets
+++ b/eng/targetingpacks.targets
@@ -66,14 +66,14 @@
RuntimeFrameworkName="$(LocalFrameworkOverrideName)"
LatestRuntimeFrameworkVersion="$(ProductVersion)"
RuntimePackNamePatterns="$(LocalFrameworkOverrideName).Runtime.NativeAOT.**RID**"
- RuntimePackRuntimeIdentifiers="ios-arm64;iossimulator-arm64;iossimulator-x64;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;maccatalyst-arm64;maccatalyst-x64;linux-bionic-arm64;linux-bionic-x64;android-x64;android-arm64;osx-arm64;osx-x64"
+ RuntimePackRuntimeIdentifiers="ios-arm64;iossimulator-arm64;iossimulator-x64;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;maccatalyst-arm64;maccatalyst-x64;linux-bionic-arm64;linux-bionic-x64;osx-arm64;osx-x64"
RuntimePackLabels="NativeAOT"
Condition="'$(UseLocalTargetingRuntimePack)' == 'true' and ('@(KnownRuntimePack)' == '' or @(KnownRuntimePack->WithMetadataValue('Identity', 'Microsoft.NETCore.App')->WithMetadataValue('RuntimePackLabels', 'NativeAOT')->WithMetadataValue('TargetFramework', '$(NetCoreAppCurrent)')) == '')" />
Date: Thu, 31 Jul 2025 17:24:18 +0000
Subject: [PATCH 18/33] Run release build in CI
---
.../extra-platforms/runtime-extra-platforms-android.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
index a9a350f4cb0446..e9e5749e9fb037 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
@@ -123,7 +123,7 @@ jobs:
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Debug
+ buildConfig: Release
runtimeFlavor: nativeaot
platforms:
- android_x64
From 972719a6af3321466c8db9cab8c69fb9faf52d2e Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 31 Jul 2025 17:27:09 +0000
Subject: [PATCH 19/33] Use AppBundle as AndroidBundleDir as Helix expects
---
src/mono/msbuild/android/build/AndroidBuild.targets | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets
index 3604334079758c..7efae9a6fe0a57 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.targets
+++ b/src/mono/msbuild/android/build/AndroidBuild.targets
@@ -34,7 +34,7 @@
$([MSBuild]::NormalizeDirectory($(PublishDir)))
- $([MSBuild]::NormalizeDirectory('$(OutDir)', 'Bundle'))
+ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
$(AndroidBundleDir)
From 0e306b2c5fd9e4cacacb9dca1c6e1f1be192f29e Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 31 Jul 2025 20:32:55 +0000
Subject: [PATCH 20/33] Tighten OutputType condition in singlefile test targets
---
eng/testing/tests.singlefile.targets | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets
index 13384fa0550b17..05b2c15a018946 100644
--- a/eng/testing/tests.singlefile.targets
+++ b/eng/testing/tests.singlefile.targets
@@ -1,8 +1,8 @@
- Exe
+ Exe
- $([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish'))
+ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish'))
$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))
$(TargetRid)
From 2b93e8350e4bfb5fb075629cc7a5eaeb9310ce9d Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:30:29 +0000
Subject: [PATCH 21/33] Add job to runtime-extra-platforms-androidemulator.yml
---
...untime-extra-platforms-androidemulator.yml | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
index 6b8698f3bdcca5..ed31308b223b12 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
@@ -149,3 +149,45 @@ jobs:
parameters:
creator: dotnet-bot
testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig)
+
+#
+# Android arm64 devices and x64 emulators
+# Build the whole product using CoreCLR and run functional tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: nativeaot
+ platforms:
+ - android_x64
+ - android_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: coreclrContainsChange
+ value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: NativeAOT
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
+ timeoutInMinutes: 120
+ condition: >-
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isRollingBuild'], true))
+ # extra steps, run tests
+ postBuildSteps:
+ - template: /eng/pipelines/libraries/helix.yml
+ parameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['coreclrContainsChange'], true),
+ eq(variables['isRollingBuild'], true))
From 7137d3685a38df1652c6c7f7722e2bf6c3e312d2 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:36:09 +0000
Subject: [PATCH 22/33] Update CrossCompileAbi condition
---
.../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index 7b56d9d928015c..0a4a1fa28b6155 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -47,10 +47,10 @@ The .NET Foundation licenses this file to you under the MIT license.
armv7
gnu
- android21
+ android21
musl
gnueabihf
- androideabi21
+ androideabi21
musleabihf
From acdb04bd26d77147db9f2a90a71e6d6fd878dd81 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 17:08:23 +0000
Subject: [PATCH 23/33] Add Collections tests project to android nativeaot test
list
---
eng/testing/tests.android.targets | 15 +++++++-
eng/testing/tests.mobile.targets | 2 +-
eng/testing/tests.singlefile.targets | 2 +-
.../Microsoft.NETCore.Native.Publish.targets | 3 +-
.../Microsoft.NETCore.Native.Unix.targets | 4 +-
.../Microsoft.NETCore.Native.targets | 3 +-
.../ILCompiler/ConfigurablePInvokePolicy.cs | 8 +++-
.../SingleFileTestRunner.cs | 2 +-
src/libraries/tests.proj | 1 +
.../msbuild/android/build/AndroidBuild.props | 7 ++--
.../Templates/monodroid-nativeaot.cs | 38 +++++++++++++++++--
...roid.Device_Emulator.NativeAOT.Test.csproj | 7 ----
.../Device_Emulator/NativeAOT/Program.cs | 2 +-
13 files changed, 69 insertions(+), 25 deletions(-)
diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index 5bcd9d4bc63d2e..ba73be79038df9 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -12,10 +12,20 @@
AndroidBuild
-
+
$(DefineConstants);SINGLE_FILE_TEST_RUNNER
+
+
+
+
+
+ true
+ <_UseLibPrefix>true
+ lib$(TargetName).so
+
+
@@ -25,7 +35,8 @@
- AndroidTestRunner.dll
+ AndroidTestRunner.dll
+ $(TargetName).so
$(PublishDir)
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 685c3b98aff181..1c0ed5772ab653 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -1,7 +1,7 @@
- $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
+ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
$(AppBundleRoot)tests\$(AssemblyName)
$(AppBundleRoot)runonly\$(AssemblyName)
$([MSBuild]::NormalizeDirectory('$(PublishDir)', 'AppBundle'))
diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets
index 05b2c15a018946..709467b7aad17d 100644
--- a/eng/testing/tests.singlefile.targets
+++ b/eng/testing/tests.singlefile.targets
@@ -32,7 +32,7 @@
true
-
+
$(DefineConstants);SINGLE_FILE_TEST_RUNNER
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
index d03686a45a2203..1ba44cff534e5a 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
@@ -28,9 +28,8 @@
- <_NativeIntermediateAssembly Include="@(IntermediateAssembly->'$(NativeOutputPath)%(Filename)$(NativeBinaryExt)')" />
-
+
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index 0a4a1fa28b6155..ac49caf95173f2 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -25,6 +25,7 @@ The .NET Foundation licenses this file to you under the MIT license.
lld
bfd
1572864
+ <_UseLibPrefix Condition="'$(_UseLibPrefix)' == ''">false
@@ -145,10 +146,11 @@ The .NET Foundation licenses this file to you under the MIT license.
+
-
+
$(IlcFrameworkNativePath)lib%(Identity).a
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
index c1a3aee2d3c86a..4fa853dc3c32ae 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
@@ -79,7 +79,8 @@ The .NET Foundation licenses this file to you under the MIT license.
.exports
$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)
- $(NativeOutputPath)$(TargetName)$(NativeBinaryExt)
+ $(NativeOutputPath)lib$(TargetName)$(NativeBinaryExt)
+ $(NativeOutputPath)$(TargetName)$(NativeBinaryExt)
true
$(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)
diff --git a/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs b/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs
index 27d6108eb70e9e..a38bcce51a3b8e 100644
--- a/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs
+++ b/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs
@@ -92,9 +92,15 @@ private IEnumerable ModuleNameVariations(string name)
else
{
string suffix = _target.IsApplePlatform ? ".dylib" : ".so";
+ bool hasSharedLibraryExtension = name.EndsWith(suffix, StringComparison.Ordinal);
+ bool hasLibPrefix = name.StartsWith("lib", StringComparison.Ordinal);
- if (name.EndsWith(suffix, StringComparison.Ordinal))
+ if (hasSharedLibraryExtension)
yield return name.Substring(0, name.Length - suffix.Length);
+ if (hasLibPrefix)
+ yield return name.Substring(3);
+ if (hasLibPrefix && hasSharedLibraryExtension)
+ yield return name.Substring(3, name.Length - suffix.Length - 3);
}
}
diff --git a/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs b/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
index 86991cbd9bc4db..f6901de13306f1 100644
--- a/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
+++ b/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
@@ -65,7 +65,7 @@ public static int Main(string[] args)
var assemblyConfig = new TestAssemblyConfiguration()
{
// Turn off pre-enumeration of theories, since there is no theory selection UI in this runner
- PreEnumerateTheories = false,
+ PreEnumerateTheories = true,
};
var xunitTestFx = new SingleFileTestRunner(diagnosticSink);
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 97482f934f1106..6aa40c375d366c 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -608,6 +608,7 @@
+
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index c5a1d39045cdfd..15a85783dc368e 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -24,6 +24,7 @@
$(ANDROID_NDK_ROOT)\toolchains\llvm\prebuilt\$(NdkToolchainPrebuiltOS)\bin\clang
Publish
+
$(_ReadRuntimeComponentsManifestTargetName);
_InitializeCommonProperties;
@@ -43,9 +44,9 @@
_AfterAndroidBuild
- $(AndroidBuildDependsOn);
- CopyNativeBinary;
- _CopyAotSymbols
+ CopyNativeBinary;
+ _CopyAotSymbols;
+ $(AndroidBuildDependsOn)
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
index 755963ad342df0..d434e673af7b15 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -9,6 +9,7 @@
using JObject = nint;
using JString = nint;
using JObjectArray = nint;
+using JSize = int;
namespace MonoDroid.NativeAOT;
@@ -41,7 +42,21 @@ public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JS
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_execEntryPoint")]
public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPointLibName, JObjectArray j_args)
{
- return Program.Main();
+ int argc = env->GetArrayLength(j_args);
+ string[] args = new string[argc];
+ for (int i = 0; i < argc; i++)
+ {
+ JObject j_arg = env->GetObjectArrayElement(j_args, i);
+ args[i] = env->GetStringUTFChars((JString)j_arg);
+ }
+
+#if SINGLE_FILE_TEST_RUNNER
+ // SingleFile unit tests
+ return SingleFileTestRunner.Main(args);
+#else
+ // Functional tests
+ return Program.Main(args);
+#endif
}
// void Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
@@ -80,6 +95,22 @@ public string GetStringUTFChars(JString str)
}
}
+ public JSize GetArrayLength(JObjectArray array)
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ return NativeInterface->GetArrayLength(thisptr, array);
+ }
+ }
+
+ public JObject GetObjectArrayElement(JObjectArray array, int index)
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ return NativeInterface->GetObjectArrayElement(thisptr, array, index);
+ }
+ }
+
[StructLayout(LayoutKind.Sequential)]
unsafe struct JNINativeInterface
{
@@ -304,11 +335,10 @@ unsafe struct JNINativeInterface
delegate* unmanaged[Cdecl] GetStringUTFLength;
public delegate* unmanaged[Cdecl] GetStringUTFChars;
public delegate* unmanaged[Cdecl] ReleaseStringUTFChars;
-
- void* GetArrayLength;
+ public delegate* unmanaged[Cdecl] GetArrayLength;
void* NewObjectArray;
- void* GetObjectArrayElement;
+ public delegate* unmanaged[Cdecl] GetObjectArrayElement;
void* SetObjectArrayElement;
void* NewBooleanArray;
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
index 15886021dd3d62..54f275fe9a3565 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
@@ -4,19 +4,12 @@
Library
true
$(NetCoreAppCurrent)
- lib$(MSBuildProjectName)
- $(TargetName).so
42
true
true
true
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
index f8430023829079..136a417dddf7f0 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
@@ -5,7 +5,7 @@
public class Program
{
- public static int Main()
+ public static int Main(string[] args)
{
string message = "Hello, Android!";
Console.WriteLine(message); // logcat
From 4e91c920a4775b32c7df633762d9aacca0a31b52 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 21:33:13 +0000
Subject: [PATCH 24/33] Use UseNativeAOTRuntime property to test if using
nativeaot instead of creating a nativeaot RuntimeFlavor
---
.../extra-platforms/runtime-extra-platforms-android.yml | 4 ++--
.../runtime-extra-platforms-androidemulator.yml | 4 ++--
src/libraries/tests.proj | 2 +-
src/mono/msbuild/android/build/AndroidBuild.props | 3 +--
4 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
index e9e5749e9fb037..27d944df93e570 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
@@ -124,7 +124,7 @@ jobs:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
- runtimeFlavor: nativeaot
+ runtimeFlavor: coreclr
platforms:
- android_x64
- android_arm64
@@ -137,7 +137,7 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=coreclr /p:TestNativeAOT=true
timeoutInMinutes: 120
condition: >-
or(
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
index ed31308b223b12..693931263a2dac 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
@@ -159,7 +159,7 @@ jobs:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
- runtimeFlavor: nativeaot
+ runtimeFlavor: coreclr
platforms:
- android_x64
- android_arm64
@@ -172,7 +172,7 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
- buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=nativeaot /p:TestNativeAOT=true
+ buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=coreclr /p:TestNativeAOT=true
timeoutInMinutes: 120
condition: >-
or(
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 6aa40c375d366c..74072efff806e8 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -606,7 +606,7 @@
-
+
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index 15a85783dc368e..6abfd8adfba125 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -3,7 +3,7 @@
$(TargetOS)-$(TargetArchitecture.ToLowerInvariant())
- false
+ false
true
true
@@ -14,7 +14,6 @@
<_IsLibraryMode Condition="'$(UseMonoRuntime)' == 'true' and '$(UseNativeAOTRuntime)' != 'true' and '$(NativeLib)' != ''">true
<_ReadRuntimeComponentsManifestTargetName Condition="'$(UseMonoRuntime)' == 'true' and '$(UseNativeAOTRuntime)' != 'true'">_MonoReadAvailableComponentsManifest
- false
false
From 36f02b84ba9483b4e17758e8fd0d0d78f330fa92 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 21:34:05 +0000
Subject: [PATCH 25/33] DirectPInvoke and DirectPInvokeList is not plural in
naot
---
src/mono/msbuild/android/build/AndroidBuild.targets | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets
index 7efae9a6fe0a57..be673d57eed15b 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.targets
+++ b/src/mono/msbuild/android/build/AndroidBuild.targets
@@ -184,10 +184,10 @@
a list of direct pinvokes otherwise the runtime will crash
-->
-
-
-
-
+
+
+
+
@@ -202,8 +202,8 @@
AsOptions="$(_AsOptions)"
Assemblies="@(_AotInputAssemblies)"
CompilerBinaryPath="$(_CompilerBinaryPath)"
- DirectPInvokes="@(DirectPInvokes)"
- DirectPInvokeLists="@(DirectPInvokeLists)"
+ DirectPInvokes="@(DirectPInvoke)"
+ DirectPInvokeLists="@(DirectPInvokeList)"
EnableUnmanagedCallersOnlyMethodsExport="$(_EnableUnmanagedCallersOnlyMethodsExport)"
IntermediateOutputPath="$(_MobileIntermediateOutputPath)"
LdName="$(_LdName)"
From aaaa078bbe38f2b600e776d15da09ce306263569 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 5 Aug 2025 21:11:53 +0000
Subject: [PATCH 26/33] Add args to main, don't run all coreclr test projects
on nativeaot android
---
src/libraries/tests.proj | 2 +-
.../FunctionalTests/Android/Device_Emulator/JIT/Program.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 74072efff806e8..db3a6d7e3f9aa0 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -594,7 +594,7 @@
-
+
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
index 81bf00c64bc256..b685e385fd0b60 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
@@ -5,7 +5,7 @@
public class Program
{
- public static int Main()
+ public static int Main(string[] args)
{
Console.WriteLine("Hello, Android!"); // logcat
return 42;
From 377e8e56eabd5bc4ccfb67bbc9d6f9c4d5dff24f Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 11 Aug 2025 19:27:16 +0000
Subject: [PATCH 27/33] Working Crypto tests
---
eng/testing/AndroidRunnerTemplate.sh | 2 +-
eng/testing/BionicRunnerTemplate.sh | 2 +-
eng/testing/tests.android.targets | 1 -
.../Microsoft.NETCore.Native.Unix.targets | 2 +-
.../CompositeMLDsa/CompositeMLDsaFactoryTests.cs | 3 ++-
.../CompositeMLDsa/CompositeMLDsaTestData.cs | 6 ++++--
.../tests/DefaultECDsaProvider.Android.cs | 4 ++--
.../tests/Rfc2898OneShotTests.cs | 1 +
.../CertificateCreation/CrlBuilderTests.cs | 1 +
.../tests/X509Certificates/TestFiles.cs | 3 ++-
src/libraries/tests.proj | 14 ++++++++++----
.../AndroidAppBuilder/Templates/MonoRunner.java | 1 +
.../Templates/monodroid-nativeaot.cs | 6 +++++-
13 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/eng/testing/AndroidRunnerTemplate.sh b/eng/testing/AndroidRunnerTemplate.sh
index d981d240c816f9..d4a760c5e4e90e 100644
--- a/eng/testing/AndroidRunnerTemplate.sh
+++ b/eng/testing/AndroidRunnerTemplate.sh
@@ -20,7 +20,7 @@ LOCKDIR=/tmp/androidtests.lock
while true; do
if mkdir "$LOCKDIR"
then
- trap 'rm -rf "$LOCKDIR"' 0
+ trap 'rm -rf "$LOCKDIR"' EXIT INT TERM HUP QUIT
break
else
sleep 5
diff --git a/eng/testing/BionicRunnerTemplate.sh b/eng/testing/BionicRunnerTemplate.sh
index 0a4911a1c5b858..a53c298652f580 100644
--- a/eng/testing/BionicRunnerTemplate.sh
+++ b/eng/testing/BionicRunnerTemplate.sh
@@ -30,7 +30,7 @@ LOCKDIR=/tmp/androidtests.lock
while true; do
if mkdir "$LOCKDIR"
then
- trap 'rm -rf "$LOCKDIR"' 0
+ trap 'rm -rf "$LOCKDIR"' EXIT INT TERM HUP QUIT
break
else
sleep 5
diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index ba73be79038df9..438e5c03b5bf2a 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -18,7 +18,6 @@
-
true
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index ac49caf95173f2..d3a6d540f6d735 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -51,7 +51,7 @@ The .NET Foundation licenses this file to you under the MIT license.
android21
musl
gnueabihf
- androideabi21
+ androideabi21
musleabihf
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
index d5997d722d8b85..08e8005028f585 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
@@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.DotNet.RemoteExecutor;
+using Microsoft.DotNet.XUnitExtensions;
using Xunit;
using Xunit.Sdk;
@@ -171,7 +172,7 @@ private static void AssertImportBadPublicKey(CompositeMLDsaAlgorithm algorithm,
}
[Theory]
- [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))]
+ [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorithm)
{
AssertThrowIfNotSupported(() =>
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
index e6bf7084e25a8b..97b2b4e310d8a1 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
@@ -43,8 +43,10 @@ internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, str
internal static CompositeMLDsaTestVector[] SupportedAlgorithmIetfVectors =>
field ??= AllIetfVectors.Where(v => CompositeMLDsa.IsAlgorithmSupported(v.Algorithm)).ToArray();
- public static IEnumerable
+
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
index c384a85066804b..c74e585836a573 100644
--- a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
+++ b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
@@ -91,6 +91,7 @@ public static void initializeRuntime(String entryPointLibName, Context context)
// set environment variables
setEnv("HOME", filesDir);
+ setEnv("ASSETS_DIR", filesDir);
setEnv("TMPDIR", cacheDir);
setEnv("TEST_RESULTS_DIR", testResultsDir);
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
index d434e673af7b15..afcfd8ab791d11 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -22,6 +22,7 @@ public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_va
{
string key = env->GetStringUTFChars(j_key);
string value = env->GetStringUTFChars(j_value);
+ Console.WriteLine($"SetEnv: {key} = {value}");
Environment.SetEnvironmentVariable(key, value);
}
@@ -29,6 +30,7 @@ public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_va
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_initRuntime")]
public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JString j_entryPointLibName, long current_local_time)
{
+ Console.WriteLine("Initializing Android crypto native library");
// The NativeAOT runtime does not need to be initialized, but the crypto library does.
JavaVM* javaVM = env->GetJavaVM();
AndroidCryptoNative_InitLibraryOnLoad(javaVM, null);
@@ -50,9 +52,11 @@ public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPoint
args[i] = env->GetStringUTFChars((JString)j_arg);
}
+ Console.WriteLine("args: " + string.Join(' ', args));
+
#if SINGLE_FILE_TEST_RUNNER
// SingleFile unit tests
- return SingleFileTestRunner.Main(args);
+ return SingleFileTestRunner.Main(["-notrait", "category=IgnoreForCI", "-notrait", "category=OuterLoop", "-notrait", "category=failing", "-notrait", "category=nonlinuxtests"]);
#else
// Functional tests
return Program.Main(args);
From 30eda43960eb612c84c5754bd5ba91ced5400e81 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 11 Aug 2025 20:50:29 +0000
Subject: [PATCH 28/33] Fix tests after merge
---
eng/testing/tests.android.targets | 2 +-
.../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 1 -
.../CompositeMLDsa/CompositeMLDsaFactoryTests.cs | 4 ++++
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index 438e5c03b5bf2a..1298f64d438b5c 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -21,7 +21,7 @@
true
- <_UseLibPrefix>true
+ <_UseNativeLibPrefix>true
lib$(TargetName).so
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index c537018a06da8d..ed5eb27be3cc6e 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -25,7 +25,6 @@ The .NET Foundation licenses this file to you under the MIT license.
lld
bfd
1572864
- <_UseLibPrefix Condition="'$(_UseLibPrefix)' == ''">false
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
index 6a81f475b2e9f8..04387127594270 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
@@ -61,6 +61,7 @@ public static void ImportBadPrivateKey_ShortTradKey(CompositeMLDsaAlgorithm algo
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -323,6 +324,7 @@ public static void ImportBadPublicKey_ShortTradKey(CompositeMLDsaAlgorithm algor
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -333,6 +335,7 @@ public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.Compos
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedECDsaAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_ECDsa_Uncompressed(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -442,6 +445,7 @@ public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorith
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
From b112dc11b3b26b5a95694b509e57773b699ce93c Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 11 Aug 2025 22:10:13 +0000
Subject: [PATCH 29/33] Add Globalization and Interop tests for NAOT on Android
---
.../SingleFileTestRunner/SingleFileTestRunner.cs | 2 +-
.../CompositeMLDsa/CompositeMLDsaFactoryTests.cs | 2 +-
.../CompositeMLDsa/CompositeMLDsaTestData.cs | 2 --
src/libraries/tests.proj | 13 +++----------
4 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs b/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
index f6901de13306f1..86991cbd9bc4db 100644
--- a/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
+++ b/src/libraries/Common/tests/SingleFileTestRunner/SingleFileTestRunner.cs
@@ -65,7 +65,7 @@ public static int Main(string[] args)
var assemblyConfig = new TestAssemblyConfiguration()
{
// Turn off pre-enumeration of theories, since there is no theory selection UI in this runner
- PreEnumerateTheories = true,
+ PreEnumerateTheories = false,
};
var xunitTestFx = new SingleFileTestRunner(diagnosticSink);
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
index 04387127594270..3d06e97302720d 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
@@ -432,7 +432,7 @@ private static void AssertImportBadPublicKey(CompositeMLDsaAlgorithm algorithm,
}
[Theory]
- [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))]
+ [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorithm)
{
AssertThrowIfNotSupported(
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
index 3b3bb2c8b8ea06..385d1765a74e68 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
@@ -43,8 +43,6 @@ internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, str
internal static CompositeMLDsaTestVector[] SupportedAlgorithmIetfVectors =>
field ??= AllIetfVectors.Where(v => CompositeMLDsa.IsAlgorithmSupported(v.Algorithm)).ToArray();
- public static bool AreAlgorithmIetfVectorsSupported => SupportedAlgorithmIetfVectors.Any();
-
public static IEnumerable SupportedAlgorithmIetfVectorsTestData =>
SupportedAlgorithmIetfVectors.Select(v => new object[] { v });
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 294a66a14a0e31..6507073fac64b3 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -610,18 +610,11 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
From 97227576ee0770477f0f358c241945e2d2b23109 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 11 Aug 2025 22:21:09 +0000
Subject: [PATCH 30/33] Remove extraneous changes
---
eng/testing/AndroidRunnerTemplate.sh | 2 +-
eng/testing/BionicRunnerTemplate.sh | 2 +-
eng/testing/tests.android.targets | 3 +--
.../CompositeMLDsa/CompositeMLDsaTestData.cs | 4 ++--
src/libraries/tests.proj | 8 ++------
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 7 +------
6 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/eng/testing/AndroidRunnerTemplate.sh b/eng/testing/AndroidRunnerTemplate.sh
index d4a760c5e4e90e..d981d240c816f9 100644
--- a/eng/testing/AndroidRunnerTemplate.sh
+++ b/eng/testing/AndroidRunnerTemplate.sh
@@ -20,7 +20,7 @@ LOCKDIR=/tmp/androidtests.lock
while true; do
if mkdir "$LOCKDIR"
then
- trap 'rm -rf "$LOCKDIR"' EXIT INT TERM HUP QUIT
+ trap 'rm -rf "$LOCKDIR"' 0
break
else
sleep 5
diff --git a/eng/testing/BionicRunnerTemplate.sh b/eng/testing/BionicRunnerTemplate.sh
index a53c298652f580..0a4911a1c5b858 100644
--- a/eng/testing/BionicRunnerTemplate.sh
+++ b/eng/testing/BionicRunnerTemplate.sh
@@ -30,7 +30,7 @@ LOCKDIR=/tmp/androidtests.lock
while true; do
if mkdir "$LOCKDIR"
then
- trap 'rm -rf "$LOCKDIR"' EXIT INT TERM HUP QUIT
+ trap 'rm -rf "$LOCKDIR"' 0
break
else
sleep 5
diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index 1298f64d438b5c..1cc807a1e6c96d 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -22,7 +22,6 @@
true
<_UseNativeLibPrefix>true
- lib$(TargetName).so
@@ -35,7 +34,7 @@
AndroidTestRunner.dll
- $(TargetName).so
+ lib$(TargetName).so
$(PublishDir)
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
index 385d1765a74e68..65bb8c366609a9 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs
@@ -43,8 +43,8 @@ internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, str
internal static CompositeMLDsaTestVector[] SupportedAlgorithmIetfVectors =>
field ??= AllIetfVectors.Where(v => CompositeMLDsa.IsAlgorithmSupported(v.Algorithm)).ToArray();
- public static IEnumerable SupportedAlgorithmIetfVectorsTestData =>
- SupportedAlgorithmIetfVectors.Select(v => new object[] { v });
+ public static IEnumerableSupportedAlgorithmIetfVectorsTestData =>
+ SupportedAlgorithmIetfVectors.Select(v => new object[] { v });
public static IEnumerable SupportedECDsaAlgorithmIetfVectorsTestData =>
SupportedAlgorithmIetfVectors
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 6507073fac64b3..4d34ad58f78752 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -594,20 +594,16 @@
-
-
-
-
-
-
+
+
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 4e5f870443287f..109583df46120f 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -475,13 +475,8 @@ public ApkBuilder(TaskLoggingHelper logger)
if (classFiles.Length == 0)
throw new InvalidOperationException("Didn't find any .class files");
- List inputFiles = [.. classFiles];
- if (IsNativeAOT)
- {
- inputFiles.Add(Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(AppDir)!)!, "libSystem.Security.Cryptography.Native.Android.jar"));
- }
- Utils.RunProcess(logger, androidSdkHelper.D8Path, $"--no-desugaring {string.Join(" ", inputFiles)}", workingDir: OutputDir);
+ Utils.RunProcess(logger, androidSdkHelper.D8Path, $"--no-desugaring {string.Join(" ", classFiles)}", workingDir: OutputDir);
}
else
{
From b7af561de7dda45ab777b1828599ad331332b7de Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 12 Aug 2025 19:06:15 +0000
Subject: [PATCH 31/33] Use xunit-excludes file for -notrait args
---
.../Templates/monodroid-nativeaot.cs | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
index 72fd2daec92dec..81f5027528423d 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -1,10 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Runtime.InteropServices;
-using System.Runtime;
using System;
+using System.IO;
+using System.Linq;
+using System.Runtime;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using JObject = nint;
using JString = nint;
@@ -55,11 +57,14 @@ public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPoint
args[i] = env->GetStringUTFChars((JString)j_arg);
}
- Console.WriteLine("args: " + string.Join(' ', args));
-
#if SINGLE_FILE_TEST_RUNNER
+ string excludesFile = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "xunit-excludes.txt");
+ if (File.Exists(excludesFile))
+ {
+ args = args.Concat(File.ReadAllLines(excludesFile).SelectMany(trait => new string[]{"-notrait", trait})).ToArray();
+ }
// SingleFile unit tests
- return SingleFileTestRunner.Main(["-notrait", "category=IgnoreForCI", "-notrait", "category=OuterLoop", "-notrait", "category=failing", "-notrait", "category=nonlinuxtests"]);
+ return SingleFileTestRunner.Main(args);
#else
// Functional tests
return Program.Main(args);
@@ -117,7 +122,7 @@ public JSize GetArrayLength(JObjectArray array)
}
}
- public JObject GetObjectArrayElement(JObjectArray array, int index)
+ public JObject GetObjectArrayElement(JObjectArray array, JSize index)
{
fixed (JNIEnv* thisptr = &this)
{
From b3ef5b1e94fc53d04226acea9719ac56295baa4a Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 12 Aug 2025 19:18:41 +0000
Subject: [PATCH 32/33] Remove System.IO.Ports.Native from
NetCoreAppNativeLibrary
---
.../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index ed5eb27be3cc6e..b2a3765eefb80d 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -145,7 +145,6 @@ The .NET Foundation licenses this file to you under the MIT license.
-
From a02ba75d4bf06179678dfe5a9d1380cda739fde5 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 13 Aug 2025 17:30:55 +0000
Subject: [PATCH 33/33] Condition OpenSsl test on IsOpenSslSupported
---
.../Common/tests/TestUtilities/System/PlatformDetection.cs | 2 +-
.../System.Security.Cryptography/tests/Rfc2898OneShotTests.cs | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
index ebdd48c679fc97..35e04300e49b3f 100644
--- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
+++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
@@ -287,7 +287,7 @@ public static bool IsMetadataTokenSupported
public static bool IsDomainJoinedMachine => !Environment.MachineName.Equals(Environment.UserDomainName, StringComparison.OrdinalIgnoreCase);
public static bool IsNotDomainJoinedMachine => !IsDomainJoinedMachine;
- public static bool IsOpenSslSupported => IsLinux || IsFreeBSD || Isillumos || IsSolaris;
+ public static bool IsOpenSslSupported => (IsLinux && !IsAndroid) || IsFreeBSD || Isillumos || IsSolaris;
public static bool OpenSslNotPresentOnSystem => !OpenSslPresentOnSystem;
public static bool UsesAppleCrypto => IsOSX || IsMacCatalyst || IsiOS || IstvOS;
diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
index 4d4978bcecac1e..48a2d1ba096093 100644
--- a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
@@ -285,9 +285,8 @@ public static void Pbkdf2_Rfc6070(string password, string salt, int iterations,
Assert.Equal(expected, actual);
}
- [Theory]
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsOpenSslSupported))]
[MemberData(nameof(Pbkdf2_OpenSsl_Vectors))]
- [SkipOnPlatform(TestPlatforms.Android, "OpenSsl is not supported on Android")]
public static void Pbkdf2_OpenSsl(string hashAlgorithm, string password, string salt, int iterations, string expectedHex)
{
HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm);