Skip to content

[TrimmableTypeMap] Package ReadyToRun trimmable typemap assemblies#11473

Open
simonrozsival wants to merge 1 commit into
mainfrom
dev/simonrozsival/trimmable-typemap-r2r-packaging
Open

[TrimmableTypeMap] Package ReadyToRun trimmable typemap assemblies#11473
simonrozsival wants to merge 1 commit into
mainfrom
dev/simonrozsival/trimmable-typemap-r2r-packaging

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

@simonrozsival simonrozsival commented May 24, 2026

Summary

  • flow generated trimmable TypeMap assemblies through ResolvedFileToPublish so crossgen2 processes them
  • replace linked TypeMap publish items with the R2R outputs before Android packaging
  • extend the CoreCLR trimmable TypeMap packaging test to prove the packaged entry assembly is ReadyToRun and TypeMap payloads are unique

Validation

  • MSBUILDDISABLENODEREUSE=1 ./dotnet-local.sh test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll --filter Name=CoreClrTrimmableTypeMap_PackagesReadyToRunTypeMap -v:minimal
  • git diff --check

Notes

  • Samsung smoke measurements showed only a small startup improvement, so follow-up startup optimization work will stay separate from this packaging fix.

References #10792

Add generated trimmable typemap assemblies to ResolvedFileToPublish so the .NET SDK ReadyToRun pipeline sees them, then replace linked typemap assemblies with the R2R outputs before Android packaging.

Extend the CoreCLR trimmable typemap packaging test to assert the packaged entry assembly is ReadyToRun and that typemap payloads are unique.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map labels May 24, 2026
@simonrozsival simonrozsival changed the title Package ReadyToRun trimmable typemap assemblies [TrimmableTypeMap] Package ReadyToRun trimmable typemap assemblies May 24, 2026
@simonrozsival simonrozsival marked this pull request as ready for review May 25, 2026 14:38
Copilot AI review requested due to automatic review settings May 25, 2026 14:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the CoreCLR trimmable TypeMap packaging flow so the generated TypeMap assemblies are routed through the standard publish pipeline, allowing crossgen2/ReadyToRun to process them, and adds a test to verify the packaged TypeMap entry assembly is R2R and not duplicated.

Changes:

  • Add trimmable TypeMap assemblies to ResolvedFileToPublish with PostprocessAssembly=true so CreateReadyToRunImages processes them.
  • After R2R, swap publish items to use the R2R outputs rather than the linked IL inputs.
  • Extend the CoreCLR trimmable typemap packaging test to assert R2R headers and ensure TypeMap payloads are packaged only once.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets Routes typemap assemblies through ResolvedFileToPublish for R2R and replaces linked inputs with R2R outputs.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs Adds an end-to-end packaging test validating the TypeMap entry assembly is R2R and not duplicated.

Comment on lines +48 to +60
<Target Name="_UseReadyToRunTrimmableTypeMapAssembliesForPublish"
Condition=" '$(RuntimeIdentifier)' != '' and '$(PublishReadyToRun)' == 'true' "
AfterTargets="CreateReadyToRunImages">
<ItemGroup>
<_LinkedTypeMapDlls Remove="@(_LinkedTypeMapDlls)" />
<_TypeMapDlls Remove="@(_TypeMapDlls)" />
<_TrimmableTypeMapAbi Remove="@(_TrimmableTypeMapAbi)" />
<_TrimmableTypeMapLinkedAssemblies Include="$(IntermediateOutputPath)linked\_*.TypeMap.dll;$(IntermediateOutputPath)linked\_Microsoft.Android.TypeMap*.dll" />
<_TrimmableTypeMapReadyToRunAssemblies Include="$(IntermediateOutputPath)R2R\_*.TypeMap.dll;$(IntermediateOutputPath)R2R\_Microsoft.Android.TypeMap*.dll" />
<ResolvedFileToPublish Remove="@(_TrimmableTypeMapLinkedAssemblies)" />
<ResolvedFileToPublish Remove="@(_TrimmableTypeMapReadyToRunAssemblies)" />
<ResolvedFileToPublish Include="@(_TrimmableTypeMapReadyToRunAssemblies)">
<RelativePath>%(Filename)%(Extension)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<RuntimeIdentifier>$(RuntimeIdentifier)</RuntimeIdentifier>
</ResolvedFileToPublish>
@simonrozsival
Copy link
Copy Markdown
Member Author

/review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Android PR Reviewer completed successfully!

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ LGTM — Clean simplification

Summary: This PR replaces the manual per-ABI assembly store injection (_AddTrimmableTypeMapAssembliesToStore) with a much simpler approach: flowing TypeMap assemblies through the standard ResolvedFileToPublish pipeline so the SDK's existing R2R target processes them. The post-R2R target then swaps linked IL copies for R2R images. The new test thoroughly verifies both the intermediate R2R output and the final APK contents.

Positives:

  • Significant complexity reduction (~56 lines removed, ~29 added) — the old ABI-batching logic was error-prone
  • Good use of the existing SDK pipeline (PostprocessAssembly=true) rather than reimplementing R2R integration
  • Test is well-structured: verifies PE headers for R2R, checks for duplicates in the APK, and confirms the packaged assembly is actually the R2R image

Minor suggestions (2):

  • Duplicated glob patterns across the two targets could drift — consider a shared property
  • Nullable flow in test could be cleaner

CI is green across all checks.

Generated by Android PR Reviewer for issue #11473 · ● 7.7M


Assert.IsTrue (helper.Exists ("assemblies/arm64-v8a/_Microsoft.Android.TypeMaps.dll"), "_Microsoft.Android.TypeMaps.dll should exist in the APK.");
using (var packagedTypeMap = helper.ReadEntry ("assemblies/arm64-v8a/_Microsoft.Android.TypeMaps.dll", AndroidTargetArch.Arm64)) {
Assert.IsNotNull (packagedTypeMap, "_Microsoft.Android.TypeMaps.dll should be readable from the APK.");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 💡 Testing — After Assert.IsNotNull, the nullable flow analysis still considers packagedTypeMap potentially null. Per repo conventions, avoid relying on assert-then-use patterns for null safety. Consider extracting to a local:

var stream = helper.ReadEntry ("assemblies/arm64-v8a/_Microsoft.Android.TypeMaps.dll", AndroidTargetArch.Arm64);
Assert.IsNotNull (stream, "...");
using var packagedReader = new System.Reflection.PortableExecutable.PEReader (stream);

This makes the non-null guarantee explicit and avoids a nested using block.

Rule: Test assertions must be specific

<_LinkedTypeMapDlls Remove="@(_LinkedTypeMapDlls)" />
<_TypeMapDlls Remove="@(_TypeMapDlls)" />
<_TrimmableTypeMapAbi Remove="@(_TrimmableTypeMapAbi)" />
<_TrimmableTypeMapLinkedAssemblies Include="$(IntermediateOutputPath)linked\_*.TypeMap.dll;$(IntermediateOutputPath)linked\_Microsoft.Android.TypeMap*.dll" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 💡 MSBuild targets — The _TrimmableTypeMapLinkedAssemblies glob pattern ($(IntermediateOutputPath)linked\_*.TypeMap.dll;...) is duplicated verbatim in both _AddTrimmableTypeMapToResolvedFileToPublish (line 36) and here. Since MSBuild item groups are target-scoped, this duplication is functionally necessary, but could you extract the glob strings into a property (e.g. _TrimmableTypeMapLinkedGlob) to keep them in sync? If one changes without the other, the Remove won't match and you'd get duplicate entries in ResolvedFileToPublish.

Rule: Don't duplicate item group transforms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants