Skip to content

Comments

[CoreCLR] Build R2R images for SDK assemblies in Debug builds#10761

Closed
Copilot wants to merge 7 commits intomainfrom
copilot/build-r2r-images-debug
Closed

[CoreCLR] Build R2R images for SDK assemblies in Debug builds#10761
Copilot wants to merge 7 commits intomainfrom
copilot/build-r2r-images-debug

Conversation

Copy link
Contributor

Copilot AI commented Feb 4, 2026

Reverted

The Debug R2R implementation caused test failures in multiple CoreCLR Debug build tests:

  • BuildApplicationWithAssetPackFalseCoreCLR
  • BuildApplicationWithAssetPackOutsideProjectDirectoryFalseCoreCLR
  • BuildApplicationWithAssetPackOverridesFalseCoreCLR
  • BuildApplicationWithAssetPackThatHasInvalidNameFalseCoreCLR
  • DotNetBuildandroid-arm64FalseFalseTrueCoreCLR

The simple approach of enabling PublishReadyToRun=true for Debug builds broke the build pipeline. The proper solution as described in the original issue requires a custom caching mechanism:

"Ideally, we'd R2R the SDK assemblies if we don't have a local copy with R2R image in obj/Debug/android<arch>/r2r/<assembly-name>/<version>/<assembly-name>.dll. If we have a local copy, we'd replace the original resolved SDK assembly with the one with the R2R image."

This requires a more comprehensive implementation that:

  1. Caches R2R images in a project-local directory
  2. Replaces SDK assemblies with cached R2R versions
  3. Avoids modifying the standard MSBuild R2R pipeline

Files reverted to original state:

  • Microsoft.Android.Sdk.CoreCLR.targets - R2R only for Release builds
  • BuildTest2.cs - Removed Debug R2R tests
Original prompt

This section details on the original issue you should resolve

<issue_title>[CoreCLR] Build R2R images for SDK assemblies in Debug builds</issue_title>
<issue_description>### Android framework version

net11.0-android (Preview)

Affected platform version

.NET 11

Description

To improve runtime performance in Debug builds, we could pre-compile R2R images for all the libraries (Mono.Android.dll, ideally also Microsoft.Maui.Controls.dll and other MAUI assemblies) which don't change after they are restored.

The idea is to create the R2R image only during the first Debug build for a given target RID and cache this image in the obj/Debug/<rid>/r2r directory. This step should be skipped on any subsequent builds of the app (requires a build test).

The pre-built native images need to be included in the app alongside the managed assemblies so that CoreCLR will load them and avoid JITting code at startup.

Open questions:

  • Can we build a composite image of all .NET for Android and .NET MAUI assemblies?
  • Does this change require changes to FastDev?
  • Do we need to make changes to AssemblyStoreBuilder (ClrAddIgnoredNativeImageAssembly), or is it only relevant for Release builds?

Steps to Reproduce

Did you find any workaround?

No response

Relevant log output

```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI changed the title [WIP] Build R2R images for SDK assemblies in Debug builds [CoreCLR] Enable R2R compilation for Debug builds Feb 4, 2026
Copilot AI requested a review from simonrozsival February 4, 2026 09:25
@simonrozsival
Copy link
Member

@copilot this is not what I had in mind. Only the SDK assemblies should be R2R compiled, not the application ones. We should take inspiration from dotnet/macios#24437

Ideally, we'd R2R the SDK assemblies if we don't have a local copy with R2R image in obj/Debug/android-<arch>/r2r/<assembly-name>/<version>/<assembly-name>.dll. If we have a local copy, we'd replace the original resolved SDK assembly with the one with the R2R image.

I think it would make more sense to embed the native image in the DLLs directly, since otherwise we would likely need to make changes to FastDev and I'd like to avoid doing that.

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot this is not what I had in mind. Only the SDK assemblies should be R2R compiled, not the application ones. We should take inspiration from dotnet/macios#24437

Ideall...

Revised the implementation in f5e3c15 to follow the macios approach. Now only SDK assemblies (Microsoft.Android, Microsoft.NETCore.App, Microsoft.Maui.*) are R2R compiled in Debug builds. User assemblies are excluded via PublishReadyToRunExclude for better debugging experience. The _AndroidSelectR2RAssemblies target identifies SDK assemblies by FrameworkReferenceName or NuGetPackageId and adds all other assemblies to the exclusion list.

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI changed the title [CoreCLR] Enable R2R compilation for Debug builds [CoreCLR] Build R2R images for SDK assemblies in Debug builds Feb 4, 2026
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Member

@simonrozsival simonrozsival left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot these tests failed. are these failures related to this PR?

2026-02-04T16:45:31.6526898Z [TESTLOG] Test BuildApplicationWithAssetPackFalseCoreCLR Outcome=Failed
2026-02-04T16:45:31.6650488Z 
2026-02-04T16:45:31.6746039Z   Failed BuildApplicationWithAssetPack(False,CoreCLR) [39 s]
2026-02-04T16:45:31.6863641Z   Error Message:
2026-02-04T16:45:31.6902108Z    Xamarin.ProjectTools.FailedBuildException : Build failure: MyApp.csprojBuild log recorded at D:\a\_work\1\a\TestRelease\02-04_16.40.31\temp\BuildApplicationWithAssetPackFalseCoreCLR\MyApp\build.log
2026-02-04T16:45:31.6929411Z   Stack Trace:
2026-02-04T16:45:31.6977752Z      at Xamarin.ProjectTools.Builder.BuildInternal(String projectOrSolution, String target, String[] parameters, Dictionary`2 environmentVariables, Boolean restore, String binlogName) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\Builder.cs:line 417
2026-02-04T16:45:31.7065001Z    at Xamarin.ProjectTools.ProjectBuilder.Build(XamarinProject project, Boolean doNotCleanupOnUpdate, String[] parameters, Boolean saveProject, Dictionary`2 environmentVariables) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\ProjectBuilder.cs:line 132
2026-02-04T16:45:31.7116947Z    at Xamarin.Android.Build.Tests.AssetPackTests.BuildApplicationWithAssetPack(Boolean isRelease, AndroidRuntime runtime) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\AssetPackTests.cs:line 203
2026-02-04T16:45:31.7203986Z    at InvokeStub_AssetPackTests.BuildApplicationWithAssetPack(Object, Span`1)
2026-02-04T16:45:31.7533551Z    at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2026-02-04T16:47:33.5107176Z [TESTLOG] Test BuildApplicationWithAssetPackOutsideProjectDirectoryFalseCoreCLR Outcome=Failed
2026-02-04T16:47:33.5150011Z 
2026-02-04T16:47:33.5203269Z   Failed BuildApplicationWithAssetPackOutsideProjectDirectory(False,CoreCLR) [16 s]
2026-02-04T16:47:33.5224590Z   Error Message:
2026-02-04T16:47:33.5257984Z    Xamarin.ProjectTools.FailedBuildException : Build failure: MyApp.csprojBuild log recorded at D:\a\_work\1\a\TestRelease\02-04_16.40.31\temp\BuildApplicationWithAssetPackOutsideProjectDirectoryFalseCoreCLR\MyApp\build.log
2026-02-04T16:47:33.5363575Z   Stack Trace:
2026-02-04T16:47:33.5425491Z      at Xamarin.ProjectTools.Builder.BuildInternal(String projectOrSolution, String target, String[] parameters, Dictionary`2 environmentVariables, Boolean restore, String binlogName) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\Builder.cs:line 417
2026-02-04T16:47:33.5441618Z    at Xamarin.ProjectTools.ProjectBuilder.Build(XamarinProject project, Boolean doNotCleanupOnUpdate, String[] parameters, Boolean saveProject, Dictionary`2 environmentVariables) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\ProjectBuilder.cs:line 132
2026-02-04T16:47:33.5443898Z    at Xamarin.Android.Build.Tests.AssetPackTests.BuildApplicationWithAssetPackOutsideProjectDirectory(Boolean isRelease, AndroidRuntime runtime) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\AssetPackTests.cs:line 102
2026-02-04T16:47:33.5449069Z    at InvokeStub_AssetPackTests.BuildApplicationWithAssetPackOutsideProjectDirectory(Object, Span`1)
2026-02-04T16:47:33.5518669Z    at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2026-02-04T16:50:11.3116867Z [TESTLOG] Test BuildApplicationWithAssetPackOverridesFalseCoreCLR Outcome=Failed
2026-02-04T16:50:11.3117042Z 
2026-02-04T16:50:11.3157690Z   Failed BuildApplicationWithAssetPackOverrides(False,CoreCLR) [10 s]
2026-02-04T16:50:11.3210661Z   Error Message:
2026-02-04T16:50:11.3248079Z    Xamarin.ProjectTools.FailedBuildException : Build failure: MyApp.csprojBuild log recorded at D:\a\_work\1\a\TestRelease\02-04_16.40.31\temp\BuildApplicationWithAssetPackOverridesFalseCoreCLR\MyApp\build.log
2026-02-04T16:50:11.3261064Z   Stack Trace:
2026-02-04T16:50:11.3265905Z      at Xamarin.ProjectTools.Builder.BuildInternal(String projectOrSolution, String target, String[] parameters, Dictionary`2 environmentVariables, Boolean restore, String binlogName) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\Builder.cs:line 417
2026-02-04T16:50:11.3267055Z    at Xamarin.ProjectTools.ProjectBuilder.Build(XamarinProject project, Boolean doNotCleanupOnUpdate, String[] parameters, Boolean saveProject, Dictionary`2 environmentVariables) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\ProjectBuilder.cs:line 132
2026-02-04T16:50:11.3335191Z    at Xamarin.Android.Build.Tests.AssetPackTests.BuildApplicationWithAssetPackOverrides(Boolean isRelease, AndroidRuntime runtime) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\AssetPackTests.cs:line 146
2026-02-04T16:50:11.3369685Z    at InvokeStub_AssetPackTests.BuildApplicationWithAssetPackOverrides(Object, Span`1)
2026-02-04T16:50:11.3383804Z    at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2026-02-04T16:52:02.5999706Z [TESTLOG] Test BuildApplicationWithAssetPackThatHasInvalidNameFalseCoreCLR Outcome=Failed
2026-02-04T16:52:02.6000778Z 
2026-02-04T16:52:02.6002123Z   Failed BuildApplicationWithAssetPackThatHasInvalidName(False,CoreCLR) [11 s]
2026-02-04T16:52:02.6059099Z   Error Message:
2026-02-04T16:52:02.6071331Z    Build Output did not contain error XA0140'.
2026-02-04T16:52:02.6072646Z   Stack Trace:
2026-02-04T16:52:02.6114990Z      at Xamarin.Android.Build.Tests.StringAssertEx.Contains(String text, IEnumerable`1 collection, String message) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\Utilities\BuildHelper.cs:line 55
2026-02-04T16:52:02.6163856Z    at Xamarin.Android.Build.Tests.AssetPackTests.BuildApplicationWithAssetPackThatHasInvalidName(Boolean isRelease, AndroidRuntime runtime) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\AssetPackTests.cs:line 65
2026-02-04T16:52:02.6204794Z    at InvokeStub_AssetPackTests.BuildApplicationWithAssetPackThatHasInvalidName(Object, Span`1)
2026-02-04T17:16:45.1508564Z [TESTLOG] Test DotNetBuildandroid-arm64FalseFalseTrueCoreCLR Outcome=Failed
2026-02-04T17:16:45.1508744Z 
2026-02-04T17:16:45.1608793Z   Failed DotNetBuild("android-arm64",False,False,True,CoreCLR) [12 s]
2026-02-04T17:16:45.1609503Z   Error Message:
2026-02-04T17:16:45.1609991Z    Xamarin.ProjectTools.FailedBuildException : Build failure: Test Me.csprojBuild log recorded at D:\a\_work\1\a\TestRelease\02-04_16.40.31\temp\DotNetBuildandroid-arm64FalseFalseTrueCoreCLR\build.log
2026-02-04T17:16:45.1610661Z   Stack Trace:
2026-02-04T17:16:45.1611301Z      at Xamarin.ProjectTools.Builder.BuildInternal(String projectOrSolution, String target, String[] parameters, Dictionary`2 environmentVariables, Boolean restore, String binlogName) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\Builder.cs:line 417
2026-02-04T17:16:45.1612445Z    at Xamarin.ProjectTools.ProjectBuilder.Build(XamarinProject project, Boolean doNotCleanupOnUpdate, String[] parameters, Boolean saveProject, Dictionary`2 environmentVariables) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.ProjectTools\Common\ProjectBuilder.cs:line 132
2026-02-04T17:16:45.1613479Z    at Xamarin.Android.Build.Tests.BuildTest.DotNetBuild(String runtimeIdentifiers, Boolean isRelease, Boolean aot, Boolean usesAssemblyStore, AndroidRuntime runtime) in D:\a\_work\1\s\src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\BuildTest.cs:line 107
2026-02-04T17:16:45.1614337Z    at InvokeStub_BuildTest.DotNetBuild(Object, Span`1)
2026-02-04T17:16:45.1614844Z    at System.Reflection.MethodBaseInvoker.InvokeWithManyArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

Comment on lines 219 to 221
// Verify incremental build is faster
Assert.IsTrue (secondBuildTime < firstBuildTime,
$"Second build ({secondBuildTime}) should have been faster than first build ({firstBuildTime})");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be quite flaky. Let's not focus on absolute build time, but just on skipping/not skipping targets. Remove this assertion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the flaky build time assertion in 4ab3bcc. The test now only verifies target execution: AssertTargetIsNotSkipped("CreateReadyToRunImages") for the first build and AssertTargetIsSkipped("CreateReadyToRunImages") for the second build.

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 5, 2026

@copilot these tests failed. are these failures related to this PR?

2026-02-04T16:45:31.6526898Z [TESTLOG] Test BuildApplicationWithAssetPackFalseCoreCLR Outcome=Failed...

Yes, these failures are related to this PR. The failing tests are all CoreCLR Debug builds (False,CoreCLR), and my change enables R2R by default for Debug builds (previously it was only enabled for Release).

The R2R compilation is likely failing because of an issue in the build pipeline - possibly related to crossgen2 tool availability or compatibility with certain build scenarios (asset packs, AABs). I'll investigate further to determine if we need to:

  1. Fix the underlying R2R issue for these scenarios
  2. Or restrict R2R to specific scenarios where it's known to work

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI requested a review from simonrozsival February 5, 2026 10:27
@simonrozsival simonrozsival deleted the copilot/build-r2r-images-debug branch February 5, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CoreCLR] Build R2R images for SDK assemblies in Debug builds

2 participants