From 9a3e300a2e9958996eeac93710d2136aafd6eb8f Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 4 Apr 2025 16:15:45 +0200 Subject: [PATCH 1/4] Enable R2R builds --- .../Xamarin.Android.Common.targets | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 07408951c6e..43e4ca59898 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -342,13 +342,10 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. true True False - True + True - False + False - - False <_AndroidUseMarshalMethods Condition=" '$(AndroidIncludeDebugSymbols)' == 'True' ">False <_AndroidUseMarshalMethods Condition=" '$(AndroidIncludeDebugSymbols)' != 'True' ">$(AndroidEnableMarshalMethods) @@ -2062,7 +2059,7 @@ because xbuild doesn't support framework reference assemblies. From 772de8e0aa72ea6139f3617ca5ded505270b29ff Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 7 Apr 2025 09:55:16 +0200 Subject: [PATCH 2/4] Add R2R build tests --- .../Xamarin.Android.Build.Tests/BuildTest2.cs | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 2d622b7e161..35d900540d2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -107,11 +107,8 @@ public void BuildBasicApplication ([Values (true, false)] bool isRelease, [Value } [Test] - public void BasicApplicationOtherRuntime ([Values (true, false)] bool isRelease) + public void BasicApplicationBuildCoreCLR ([Values (true, false)] bool isRelease) { - // This test would fail, as it requires **our** updated runtime pack, which isn't currently created - // It is created in `src/native/native-clr.csproj` which isn't built atm. - Assert.Ignore ("CoreCLR support isn't fully enabled yet. This test will be enabled in a follow-up PR."); var proj = new XamarinAndroidApplicationProject { IsRelease = isRelease, // Add locally downloaded CoreCLR packs @@ -124,6 +121,49 @@ public void BasicApplicationOtherRuntime ([Values (true, false)] bool isRelease) Assert.IsTrue (b.Build (proj), "Build should have succeeded."); } + static object [] ReadyToRunConfigurationSource = new object [] { + new object[] { + /* isComposite */ true, + /* rid */ "android-x64" + }, + new object[] { + /* isComposite */ false, + /* rid */ "android-x64" + }, + new object[] { + /* isComposite */ true, + /* rid */ "android-arm64" + }, + new object[] { + /* isComposite */ false, + /* rid */ "android-arm64" + } + }; + + [Test] + [TestCaseSource (nameof (ReadyToRunConfigurationSource))] + public void BasicApplicationPublishReadyToRun (bool isComposite, string rid) + { + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + // Add locally downloaded CoreCLR packs + ExtraNuGetConfigSources = { + Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned"), + } + }; + + proj.SetProperty ("RuntimeIdentifier", rid); + proj.SetProperty ("UseMonoRuntime", "false"); // Enables CoreCLR + proj.SetProperty ("_IsPublishing", "true"); // Make "dotnet build" act as "dotnet publish" + proj.SetProperty ("PublishReadyToRun", "true"); // Enable R2R + + if (isComposite) + proj.SetProperty ("PublishReadyToRunComposite", "true"); // Enable R2R composite + + var b = CreateApkBuilder (); + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + } + [Test] public void NativeAOT () { From de98b73c29da3534ec3190e406107afa94245e94 Mon Sep 17 00:00:00 2001 From: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:52:22 +0200 Subject: [PATCH 3/4] Update src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs PR feedback Co-authored-by: Jonathan Peppers --- .../Tests/Xamarin.Android.Build.Tests/BuildTest2.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 35d900540d2..65f3cb0537e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -124,19 +124,19 @@ public void BasicApplicationBuildCoreCLR ([Values (true, false)] bool isRelease) static object [] ReadyToRunConfigurationSource = new object [] { new object[] { /* isComposite */ true, - /* rid */ "android-x64" + /* rid */ "android-x64" }, new object[] { /* isComposite */ false, - /* rid */ "android-x64" + /* rid */ "android-x64" }, new object[] { /* isComposite */ true, - /* rid */ "android-arm64" + /* rid */ "android-arm64" }, new object[] { /* isComposite */ false, - /* rid */ "android-arm64" + /* rid */ "android-arm64" } }; From 619186ba56aae9b10ddde3d071d1fda753bee24a Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 17 Apr 2025 19:36:30 +0200 Subject: [PATCH 4/4] Use better verification method that app assembly in the apk has R2R image in it --- .../Xamarin.Android.Build.Tests/BuildTest2.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 65f3cb0537e..075ad1e9b3f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -156,12 +156,27 @@ public void BasicApplicationPublishReadyToRun (bool isComposite, string rid) proj.SetProperty ("UseMonoRuntime", "false"); // Enables CoreCLR proj.SetProperty ("_IsPublishing", "true"); // Make "dotnet build" act as "dotnet publish" proj.SetProperty ("PublishReadyToRun", "true"); // Enable R2R + proj.SetProperty ("AndroidEnableAssemblyCompression", "false"); if (isComposite) proj.SetProperty ("PublishReadyToRunComposite", "true"); // Enable R2R composite var b = CreateApkBuilder (); Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + + var assemblyName = proj.ProjectName; + var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, rid, $"{proj.PackageName}-Signed.apk"); + FileAssert.Exists (apk); + + var helper = new ArchiveAssemblyHelper (apk, true); + var abi = MonoAndroidHelper.RidToAbi (rid); + Assert.IsTrue (helper.Exists ($"assemblies/{abi}/{assemblyName}.dll"), $"{assemblyName}.dll should exist in apk!"); + + using var stream = helper.ReadEntry ($"assemblies/{assemblyName}.dll"); + stream.Position = 0; + using var peReader = new System.Reflection.PortableExecutable.PEReader (stream); + Assert.IsTrue (peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory.Size > 0, + $"ReadyToRun image not found in {assemblyName}.dll! ManagedNativeHeaderDirectory should not be empty!"); } [Test]