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 IEnumerableSupportedAlgorithmIetfVectorsTestData => - SupportedAlgorithmIetfVectors.Select(v => new object[] { v }); + public static bool AreAlgorithmIetfVectorsSupported => SupportedAlgorithmIetfVectors.Any(); + + public static IEnumerable SupportedAlgorithmIetfVectorsTestData => + SupportedAlgorithmIetfVectors.Select(v => new object[] { v }); internal static CompositeMLDsaAlgorithm[] AllAlgorithms => field ??= [ diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs index c12eddf33ab180..17e0574ceee9b5 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs @@ -52,8 +52,8 @@ internal static partial class Interop { internal static partial class AndroidCrypto { - [DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid")] - internal static extern System.IntPtr EcKeyCreateByOid(string oid); + [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid", StringMarshalling = StringMarshalling.Utf8)] + internal static partial System.IntPtr EcKeyCreateByOid(string oid); [DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyDestroy")] internal static extern void EcKeyDestroy(System.IntPtr r); diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs index 3a54623527d8d6..4d4978bcecac1e 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs @@ -287,6 +287,7 @@ public static void Pbkdf2_Rfc6070(string password, string salt, int iterations, [Theory] [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); diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs index 6723283a95097a..a4b3cf23a841e3 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs @@ -297,6 +297,7 @@ public static void BuildWithEmptyHashAlgorithm(CertKind certKind) [Theory] [MemberData(nameof(NoHashAlgorithmCertKinds))] + [SkipOnPlatform(TestPlatforms.Android, "No algorithms are supported")] public static void BuildPqcWithHashAlgorithm(CertKind certKind) { BuildCertificateAndRun( diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs index 7015c10fd621f3..f13d7034307e6d 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs @@ -8,7 +8,8 @@ namespace System.Security.Cryptography.X509Certificates.Tests { internal static class TestFiles { - internal const string TestDataFolder = "TestData"; + internal static readonly string? TestDataRoot = Environment.GetEnvironmentVariable("ASSETS_DIR") ?? AppContext.BaseDirectory; + internal static readonly string TestDataFolder = Path.Combine(TestDataRoot, "TestData"); // Certs internal static readonly string MsCertificateDerFile = Path.Combine(TestDataFolder, "MS.cer"); diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index db3a6d7e3f9aa0..ddcda73264147d 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -594,21 +594,27 @@ + + + + + + - - - - + + + + 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);