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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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/29] 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 b84c29494c8e23ff02de6364199baf0c513198d1 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Mon, 4 Aug 2025 10:10:16 -0700
Subject: [PATCH 23/29] Update
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
Co-authored-by: Filip Navara
---
.../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 2 +-
1 file changed, 1 insertion(+), 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 0a4a1fa28b6155..e954d8b000c47e 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -50,7 +50,7 @@ The .NET Foundation licenses this file to you under the MIT license.
android21
musl
gnueabihf
- androideabi21
+ androideabi21
musleabihf
From 904d59d81582037246598c902bc78983d43bb526 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/29] 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 97482f934f1106..f442d98ee13784 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 c5a1d39045cdfd..96513e0442f990 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 6a7b9186961b1e86a7be1fc4e5d9739747122eb2 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/29] 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 5a0413b22ee5942a32dce9c644b10741e40edb23 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 5 Aug 2025 19:43:03 +0000
Subject: [PATCH 26/29] Add null checks in JNI code
---
.../Templates/monodroid-nativeaot.cs | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
index 755963ad342df0..37b23b7a06d65d 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -19,9 +19,10 @@ internal static unsafe partial class MonoDroidExports
[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);
+ string? key = env->GetStringUTFChars(j_key);
+ string? value = env->GetStringUTFChars(j_value);
+ if (key != null && value != null)
+ 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);
@@ -58,14 +59,18 @@ public static void FreeNativeResources(JNIEnv* env, JObject thiz)
internal unsafe struct JNIEnv
{
JNINativeInterface* NativeInterface;
- public string GetStringUTFChars(JString str)
+ public string? GetStringUTFChars(JString str)
{
fixed (JNIEnv* thisptr = &this)
{
byte* chars = NativeInterface->GetStringUTFChars(thisptr, str, out byte isCopy);
+ if (chars is null)
+ return null;
+
string result = Marshal.PtrToStringUTF8((nint)chars);
if (isCopy != 0)
NativeInterface->ReleaseStringUTFChars(thisptr, str, chars);
+
return result;
}
}
@@ -75,7 +80,10 @@ public string GetStringUTFChars(JString str)
fixed (JNIEnv* thisptr = &this)
{
JavaVM* vm;
- NativeInterface->GetJavaVM(thisptr, &vm);
+ int result = NativeInterface->GetJavaVM(thisptr, &vm);
+ if (result != 0)
+ return null;
+
return vm;
}
}
From 222b80507ac336669ee9fa6543e4e85271c2dcfc Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 5 Aug 2025 19:44:40 +0000
Subject: [PATCH 27/29] Condition CoreCLR tests on the build not being for
NativeAOT
---
src/libraries/tests.proj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index f442d98ee13784..56d699b0460088 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -594,7 +594,7 @@
-
+
From b61f83c911318a2cfc1c74f35c674ac77f1683aa Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Tue, 5 Aug 2025 19:45:05 +0000
Subject: [PATCH 28/29] Run android tests unconditionally in extra-platforms
builds
---
.../runtime-extra-platforms-android.yml | 14 ++------------
.../runtime-extra-platforms-androidemulator.yml | 16 ++++------------
2 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
index 27d944df93e570..d624a1d0a5da00 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml
@@ -117,7 +117,7 @@ jobs:
#
# Android arm64 devices and x64 emulators
-# Build the whole product using CoreCLR and run functional tests
+# Build the whole product using NativeAOT and run functional tests
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -137,22 +137,12 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
+ isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
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(
- 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))
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
index 693931263a2dac..7215b782087214 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml
@@ -152,7 +152,7 @@ jobs:
#
# Android arm64 devices and x64 emulators
-# Build the whole product using CoreCLR and run functional tests
+# Build the whole product using NativeAOT and run functional tests
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -160,6 +160,8 @@ jobs:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
runtimeFlavor: coreclr
+ isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
+ isAndroidEmulatorOnlyBuild: ${{ parameters.isAndroidEmulatorOnlyBuild }}
platforms:
- android_x64
- android_arm64
@@ -172,22 +174,12 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: NativeAOT
+ isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
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(
- 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 ef83aa73730c64157893818bf6bac3629eeaaa5c Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 6 Aug 2025 05:43:19 +0000
Subject: [PATCH 29/29] Copy Java files to publish dir, don't search for them
in build dir
---
.../ComputeManagedAssembliesToCompileToNative.cs | 4 +++-
src/tasks/AndroidAppBuilder/ApkBuilder.cs | 7 +------
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
index e4c5332acaa21a..256ef76f9ed885 100644
--- a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
@@ -130,7 +130,9 @@ public override bool Execute()
continue;
}
- if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true)
+ if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true
+ && !assemblyFileName.EndsWith(".jar", StringComparison.OrdinalIgnoreCase)
+ && !assemblyFileName.EndsWith(".dex", StringComparison.OrdinalIgnoreCase))
{
// Skip the native components of the runtime pack, we don't need them for NativeAOT.
assembliesToSkipPublish.Add(taskItem);
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
{