Skip to content

[NativeAOT] Add trimmable type map build tests and decouple ILC from ILLink#11183

Open
sbomer wants to merge 10 commits intomainfrom
dev/sbomer/naot-trimmable-typemap
Open

[NativeAOT] Add trimmable type map build tests and decouple ILC from ILLink#11183
sbomer wants to merge 10 commits intomainfrom
dev/sbomer/naot-trimmable-typemap

Conversation

@sbomer
Copy link
Copy Markdown
Member

@sbomer sbomer commented Apr 22, 2026

Summary

Add build test coverage for NativeAOT with the trimmable type map, and decouple the ILC input wiring from ILLink so that NativeAOT builds work without running ILLink.

Test changes (TrimmableTypeMapBuildTests.cs)

Parameterize Build_WithTrimmableTypeMap_Succeeds and Build_WithTrimmableTypeMap_IncrementalBuild to run with both CoreCLR and NativeAOT runtimes:

Build pipeline changes (Microsoft.Android.Sdk.NativeAOT.targets)

When _AndroidTypeMapImplementation=trimmable, skip ILLink and let ILC compile directly:

  • IlcCompileDependsOn: conditionally remove PrepareForILLink and ILLink for trimmable path
  • _AndroidBeforeIlcCompile: skip _PrepareLinking dependency and ILLink-specific settings (RunILLink, SuppressTrimAnalysisWarnings, _ExtraTrimmerArgs) for trimmable path
  • _AndroidComputeIlcCompileInputs: remove the manual IlcCompileInput/IlcReference override that read from $(IntermediateLinkDir)linked/. Let the SDK's _ComputeIlcCompileInputs (from Microsoft.NETCore.Native.Publish.targets) populate IlcReference from @(ResolvedFileToPublish) using the standard PostprocessAssembly metadata contract. For the ILLink path, replace trimmed PrivateSdkAssemblies in IlcReference with untrimmed originals from the NativeAOT SDK pack (ILC needs them for --initassembly runtime infrastructure).
  • _AndroidRunNativeCompile: skip _PreTrimmingFixLegacyDesignerUpdateItems dependency for trimmable path

Context

This content was created with assistance from AI.

…pe map

Parameterize Build_WithTrimmableTypeMap_Succeeds and
Build_WithTrimmableTypeMap_IncrementalBuild to run with both CoreCLR and
NativeAOT runtimes. NativeAOT uses Release configuration (required).
CoreCLR + Release is skipped pending upstream fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 22, 2026 19:18
@sbomer sbomer added Area: NativeAOT Issues that only occur when using NativeAOT. trimmable-type-map labels Apr 22, 2026
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 adds build-test coverage for the trimmable typemap when using NativeAOT, and updates the NativeAOT MSBuild pipeline so ILC inputs are no longer hard-wired to ILLink output—allowing NativeAOT + trimmable builds to proceed without running ILLink.

Changes:

  • Parameterize TrimmableTypeMapBuildTests to run for both CoreCLR and NativeAOT (with appropriate skips/ignores).
  • Update Microsoft.Android.Sdk.NativeAOT.targets so trimmable typemap builds skip ILLink and let the SDK’s standard NativeAOT input computation drive ILC references.
  • Adjust NativeCompile scheduling/dependencies to avoid ILLink/llvm-ir typemap-specific targets in the trimmable path.

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/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs Expands trimmable typemap build tests to cover both CoreCLR and NativeAOT configurations.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets Conditions ILLink integration and ILC input wiring so trimmable typemap NativeAOT builds don’t depend on ILLink output.

@sbomer sbomer force-pushed the dev/sbomer/naot-trimmable-typemap branch from 3f37eef to f5b66c8 Compare April 22, 2026 20:28
sbomer and others added 2 commits April 22, 2026 13:43
Redesign _AndroidComputeIlcCompileInputs to populate IlcCompileInput and
IlcReference from @(ResolvedFileToPublish) instead of hardcoding the
$(IntermediateLinkDir) path.  This matches the SDK contract in
Microsoft.NETCore.Native.Publish.targets and works regardless of whether
ILLink ran.

When _AndroidTypeMapImplementation is 'trimmable':
- Remove PrepareForILLink and ILLink from IlcCompileDependsOn
- Skip _PrepareLinking dependency in _AndroidBeforeIlcCompile
- Skip ILLink-specific settings (RunILLink, SuppressTrimAnalysisWarnings)
- Skip _PreTrimmingFixLegacyDesignerUpdateItems in _AndroidRunNativeCompile

Fixes #11182

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
_OriginalSuppressTrimAnalysisWarnings is only set in the ILLink-specific
PropertyGroup (non-trimmable path). Without this condition, the restore
in _AndroidComputeIlcCompileInputs would clobber SuppressTrimAnalysisWarnings
with an empty value in the trimmable path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sbomer sbomer force-pushed the dev/sbomer/naot-trimmable-typemap branch from f5b66c8 to 2b79e92 Compare April 22, 2026 21:55
@sbomer sbomer self-assigned this Apr 22, 2026
The ILC input wiring change results in a 470 KB size reduction in the
native binary (10.2%) because the SDK's _ComputeIlcCompileInputs
provides a cleaner set of references for ILC trimming.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

I think we reduced the warnings on this one?

BuildHasNoWarnings(True,True,False,"apk",NativeAOT)

build.log should have exactly 120 MSBuild warnings for NativeAOT.
Expected: True
But was:  False

Log has 92 Warning(s).

Honestly, I don't know if we care about the exact number, maybe the assert can just assert < 92 now? (so, it doesn't grow worse)

sbomer and others added 3 commits April 23, 2026 09:55
Removing the blanket TrimMode=All rooting for ILC inputs means ILC
trims more unused code and produces fewer AOT analysis warnings
(120 -> 92). Use Assert.LessOrEqual so the test does not break if
warnings decrease further.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The trimmable path skips _PrepareLinking (ILLink-specific), but
_PrepareLinking indirectly triggered _CreatePropertiesCache which
resolves AndroidBinUtilsDirectory via _ResolveSdks. Without this,
CompileNativeAssembly fails in the inner per-RID build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NativeAOT + trimmable builds fail at Java compilation because
JavaInteropRuntime.java and NativeAotEnvironmentVars.java are not
generated by the trimmable typemap path. Tracked in #11210.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sbomer and others added 3 commits April 24, 2026 14:30
The ILLink path needs TrimmerRootAssembly TrimMode=All for all
ILLink-trimmed assemblies so ILC doesn't trim further. Without it,
ILC removes JNI callback types that are invoked from Java at runtime,
causing MemberAccessException crashes.

The trimmable path doesn't need this because it doesn't run ILLink
and ILC handles all trimming directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: NativeAOT Issues that only occur when using NativeAOT. trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[NativeAOT] Decouple ILC input wiring from ILLink output

3 participants