Repository navigation
[Microsoft.Android.Build.Tasks] Generate typemap ProGuard rules - #12821
Closed
simonrozsival wants to merge 25 commits into
Closed
simonrozsival wants to merge 25 commits into
simonrozsival wants to merge 25 commits into
Conversation
Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Parse the named Java type-name blobs in release and debug CoreCLR LLVM IR, supporting emitted byte strings and legacy integer arrays. Validate required inputs and blob data before writing canonical sorted keys, and cover emitter output and malformed inputs with focused task tests. Co-authored-by: Copilot App <[email protected]>
Inspect surviving assembly TypeMapAttribute metadata and exercise emitted assemblies through the pinned real ILLink in standalone tests. Source-link retained-key tasks for repeatable standalone coverage. Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Reject absent inputs, invalid assembly metadata and malformed typemap attributes. Reuse canonical name validation after decimal alias normalization. Resolve all fixture references for strict real-ILLink coverage and source-link the LLVM adapter for standalone tests. Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Relocate ExtractTypeMapKeysFromLlvmIr to Microsoft.Android.Build.Tasks and use its source-linked shared diagnostics. Move the emitter-backed NUnit fixture to the modern task test project using its existing aliased reference to the LLVM emitter. Preserve the task API, key format, and parser behavior. Co-authored-by: Copilot App <[email protected]>
Link existing metadata helpers into the modern task assembly and test its production binaries directly instead of source-linking task copies. Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Wire the selected modern adapter after its final producer, union per-RID inputs, generate class-only roots, and keep member retention and non-obfuscation policy separate. Track source lists and mode changes while preserving legacy and explicit override paths. Co-authored-by: Copilot App <[email protected]>
Honor _AndroidEnableTypemapR8Trimming without a default: false selects legacy retention and avoids automatic DGML, while true/unset retain supported pipeline eligibility. Invalidate stale generated rules across switch transitions. Co-authored-by: Copilot App <[email protected]>
Use _AndroidEnableTypemapR8Trimming as the sole product switch. Consume DGML only through retained-key extraction; retain optimized-only automatic selection and explicit codegen graph opt-in without the old NativeAOT switches. Co-authored-by: Copilot App <[email protected]>
Map object arrays to their canonical element class and omit primitive arrays, which do not represent Java class definitions. Keep malformed descriptors and numeric aliases invalid for LLVM inputs. Co-authored-by: Copilot App <[email protected]>
ILC emits built-in types such as int32 without assembly-qualified names. Ignore the known intrinsic labels while preserving strict validation of malformed managed identities. Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Keep class-root generation separate from scoped JNI member rules and preserve explicit CoreCLR runtime bootstrap members. Leave NativeAOT's existing policy unchanged. Normalize the modern task assembly path for incremental inputs and cover no-op/deleted-output builds plus real inherited JNI method/field access and Java-only dependency removal. Co-authored-by: Copilot App <[email protected]>
Stream relevant LLVM symbol records and bound relocation queries to avoid whole-symbol/relocation JSON allocations. Co-authored-by: Copilot App <[email protected]>
Read each RID's actual NativeObject with explicit NDK LLVM tools, select Java groups structurally, and preserve no-NDK default builds through the private opt-in. Remove automatic graphs and retire DGML diagnostics. Reconcile scoped CoreCLR member rules and normalized incremental inputs. Co-authored-by: Copilot App <[email protected]>
Keep runtime interface-collection assertions and graph-free pipeline regressions, while removing obsolete graph analysis, fixtures, serialization, and guidance. Co-authored-by: Copilot App <[email protected]>
Select the optimizing Android R8 defaults for the active CoreCLR typemap pipeline while preserving -dontobfuscate, --no-minification and all keep rules. Leave NativeAOT, legacy modes and complete configuration overrides unchanged. Cover actual config selection and R8 metadata, and allow optimizer inlining of Java-only helpers in the JNI device regression. Co-authored-by: Copilot App <[email protected]>
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Five moderate issues remain in exception handling, target gating/override behavior, and NativeAOT test capability detection.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
This PR generates retained-typemap-based ProGuard rules for CoreCLR and opt-in NativeAOT builds, replacing broad ACW/DGML retention.
Changes:
- Adds LLVM IR, assembly, and NativeAOT object typemap extraction.
- Updates MSBuild/R8 integration and incremental build behavior.
- Adds rule-generation tasks, tests, diagnostics, and documentation.
- Review found five unresolved issues requiring changes.
| File | Summary |
|---|---|
tests/MSBuildDeviceIntegration/Tests/ScopedTypeMapR8Tests.cs |
Device R8 coverage |
tests/MSBuildDeviceIntegration/Tests/InterfaceCollectionTests.cs |
Interface collection coverage |
tests/MSBuildDeviceIntegration/Tests/InterfaceCollectionRootingTests.cs |
Rooting coverage |
tests/MSBuildDeviceIntegration/Resources/InterfaceCollectionApp/rooting.dgml.xml |
DGML fixture |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TypeMapTaskBuildEngine.cs |
Test build-engine helpers |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/NativeAotObjectIntegrationTests.cs |
NativeAOT integration tests; clang capability check needs updating |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj |
Test project configuration |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/NativeAotObjectTestFixture.Tool.cs |
NativeAOT tool fixture |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/NativeAotObjectTestFixture.cs |
NativeAOT object fixture |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/ExtractTypeMapKeysFromLlvmIrArrayTests.cs |
LLVM key extraction tests |
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/ExtractTypeMapKeysFromAssembliesTests.cs |
Assembly key extraction tests |
src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets |
Tracks generated ProGuard inputs |
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets |
R8 property and pipeline integration |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs |
Build test utilities |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs |
Trimmable typemap build coverage |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/R8Tests.cs |
R8 task tests |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GenerateNativeAotProguardConfigurationTests.cs |
NativeAOT rule-generation tests |
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs |
Build regression coverage |
src/Xamarin.Android.Build.Tasks/Tasks/R8.cs |
Applies typemap R8 policies |
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeAotProguardConfiguration.cs |
NativeAOT configuration handling |
src/Xamarin.Android.Build.Tasks/Resources/proguard_typemap.cfg |
Shared ProGuard rules |
src/Xamarin.Android.Build.Tasks/Resources/proguard_typemap_coreclr.cfg |
CoreCLR ProGuard rules |
src/Xamarin.Android.Build.Tasks/Resources/proguard_trimmable_nativeaot.cfg |
NativeAOT ProGuard rules |
src/Xamarin.Android.Build.Tasks/Properties/Resources.resx |
Localized resources |
src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs |
Generated resource accessors |
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.NativeAOT.targets |
NativeAOT pipeline |
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets |
CoreCLR pipeline |
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Proguard.targets |
ProGuard pipeline; eligibility and override guards need correction |
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets |
LLVM typemap pipeline |
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets |
Assembly resolution integration |
src/Microsoft.Android.Build.Tasks/Utilities/TypeMapKey.cs |
Typemap key representation |
src/Microsoft.Android.Build.Tasks/Utilities/TypeMapClassName.cs |
JNI class-name normalization |
src/Microsoft.Android.Build.Tasks/Utilities/NativeAotTypeMapReader.cs |
NativeAOT typemap parsing |
src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/GenerateTypeMapProguardConfigurationTests.cs |
Rule-generation tests |
src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/ExtractTypeMapKeysFromLlvmIrTests.cs |
LLVM extraction tests |
src/Microsoft.Android.Build.Tasks/Tasks/GenerateTypeMapProguardConfiguration.cs |
Generates class keep rules |
src/Microsoft.Android.Build.Tasks/Tasks/GenerateTypeMapMemberProguardConfiguration.cs |
Generates member keep rules |
src/Microsoft.Android.Build.Tasks/Tasks/ExtractTypeMapKeysFromNativeAotObject.cs |
Extracts NativeAOT keys; malformed UTF-8 handling needs correction |
src/Microsoft.Android.Build.Tasks/Tasks/ExtractTypeMapKeysFromLlvmIr.cs |
Extracts LLVM keys; malformed UTF-8 handling needs correction |
src/Microsoft.Android.Build.Tasks/Tasks/ExtractTypeMapKeysFromAssemblies.cs |
Extracts assembly keys |
src/Microsoft.Android.Build.Tasks/Microsoft.Android.Build.Tasks.csproj |
Task project configuration |
Documentation/guides/D8andR8.md |
R8 pipeline documentation |
Documentation/docs-mobile/TOC.yml |
Documentation navigation |
Documentation/docs-mobile/messages/xa4328.md |
Diagnostic documentation |
Documentation/docs-mobile/messages/xa4327.md |
Diagnostic documentation |
Documentation/docs-mobile/messages/xa4321.md |
Diagnostic documentation |
Documentation/docs-mobile/messages/xa4320.md |
Diagnostic documentation |
Documentation/docs-mobile/messages/xa4319.md |
Diagnostic documentation |
Documentation/docs-mobile/messages/index.md |
Diagnostic index |
Documentation/docs-mobile/building-apps/build-properties.md |
Build property documentation |
.github/skills/tests/references/test-catalog.md |
Test prerequisite documentation |
Files not reviewed (1)
- src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file
Comment on lines
+122
to
+124
| Condition=" '$(_AndroidEnableTypemapR8Trimming)' != 'false' and '$(PublishTrimmed)' == 'true' and '$(AndroidLinkTool)' == 'r8' and '$(_ComputeFilesToPublishForRuntimeIdentifiers)' != 'true' and ('$(_AndroidRuntime)' == 'CoreCLR' or ('$(_AndroidRuntime)' == 'NativeAOT' and '$(AndroidTypeMapImplementation)' == 'trimmable' and '$(_AndroidEnableTypemapR8Trimming)' == 'true')) " | ||
| Inputs="@(_AndroidTypeMapKeyFile);$(_AndroidTypeMapTasksAssemblyFile);$(_AndroidBuildPropertiesCache)" | ||
| Outputs="$(_ProguardProjectConfiguration)"> |
This was referenced Sep 18, 2026
simonrozsival
added a commit
that referenced
this pull request
Sep 21, 2026
Complete layer 6 of the frozen #12821 split: activate the shared retained-typemap pipeline, wire R8 retention policies, remove DGML generation, and restore the deferred activation coverage and documentation. Preserve the base XA1037 localization changes. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 21, 2026
Complete layer 6 of the frozen #12821 split: activate the shared retained-typemap pipeline, wire R8 retention policies, remove DGML generation, and restore the deferred activation coverage and documentation. Preserve the base XA1037 localization changes. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 22, 2026
Layer 1 of 6 splitting #12821; build activation comes in later layers. Establish a shared retained-Java-key contract so the runtime-specific extractors can feed the same ProGuard generators without duplicating rule generation. This is a focused slice of the validated source at `87bd3f8a8b512859339e5446c1f86709a6c28c3b`, based on `main` at `d63fe4c9f8cf8def6049c9415bb0abf4269ee0f5`. ### Scope and contract - Add canonical JNI class-name and alias-key utilities. The shared interchange format is sorted, unique JNI class names, UTF-8 without BOM, with LF line endings. - Add `<GenerateTypeMapProguardConfiguration/>`, which unions canonical keys and emits only `-keep class` rules. Reject invalid names/rule injection and missing inputs before overwriting output; valid empty inputs produce empty output. - Add `<GenerateTypeMapMemberProguardConfiguration/>`, which keeps **all members of retained classes**. This is not precise-method inference. - Add shared XA4327/XA4328 diagnostics and documentation while preserving XA4319/XA4320/XA4321 and the newer base localization changes. - Add the standalone production-task reference, minimal build engine, six generator unit-test methods, and the final-source NUnit fixture. No extractors, target imports, `UsingTask` activation, R8 policy changes, runtime changes, or DGML removal are included. The standalone `TypeMapProguardTests` fixture is intentionally a generator-only subset; later layers add its adapter/target/configuration coverage. ### Validation `dotnet test tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj -v minimal --filter 'FullyQualifiedName~TypeMapProguardTests'` **15 passed, 0 failed, 0 skipped**, compiling the actual modern production task project and its source-linked shared resources. The focused NUnit command was also attempted. Its existing legacy `Xamarin.Android.Build.Tasks` project reference requires the missing `bin/BuildDebug/net10.0/xa-prep-tasks.dll` (`GitBlame`/`GitCommitHash`, MSB4062) in this clean worktree. The unchanged frozen-source fixture is retained; no full SDK/bootstrap build or test-project infrastructure changes were made. `git diff --check` passes. Complete extracted files match the frozen source byte-for-byte; retained standalone test/helper methods match the frozen source. The diff is additive only: 14 files, 546 insertions.
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Extract surviving generic TypeMapAttribute keys from linked managed assemblies, with canonical alias and array normalization and explicit malformed-input failures. Add focused production-task coverage including the pinned real ILLink fixture. Layer 3 of the #12821 split; MSBuild activation remains in a later layer. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Extract canonical Java class keys from CoreCLR LLVM string blobs without relying on optional comments. Preserve strict diagnostics and array normalization with standalone and real-emitter test fixtures. Layer 2 of 6 splitting #12821; runtime activation follows in a later layer. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Extract surviving generic TypeMapAttribute keys from linked managed assemblies, with canonical alias and array normalization and explicit malformed-input failures. Add focused production-task coverage including the pinned real ILLink fixture. Layer 3 of the #12821 split; MSBuild activation remains in a later layer. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Extract surviving generic TypeMapAttribute keys from linked managed assemblies, with canonical alias and array normalization and explicit malformed-input failures. Add focused production-task coverage including the pinned real ILLink fixture. Layer 3 of the #12821 split; MSBuild activation remains in a later layer. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Complete layer 6 of the frozen #12821 split: activate the shared retained-typemap pipeline, wire R8 retention policies, remove DGML generation, and restore the deferred activation coverage and documentation. Preserve the base XA1037 localization changes. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 23, 2026
Extract surviving generic TypeMapAttribute keys from linked managed assemblies, with canonical alias and array normalization and explicit malformed-input failures. Add focused production-task coverage including the pinned real ILLink fixture. Layer 3 of the #12821 split; MSBuild activation remains in a later layer. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Sep 24, 2026
## Why Layer 1 of 4 in the remaining #12821 stack, based on main. The foundation #12822 has merged; the LLVM adapter #12823 is closed and omitted. Typemap-derived ProGuard rules need the Java class keys that survive ILLink, rather than pre-link registration metadata or stale alias arrays. ## Changes Add `ExtractTypeMapKeysFromAssemblies` in the modern `Microsoft.Android.Build.Tasks` assembly. It reads surviving assembly-level generic `TypeMapAttribute` entries, unions and sorts their keys, normalizes alias suffixes and object-array descriptors, and writes canonical UTF-8 output. Empty linked stubs are valid; absent inputs, malformed assemblies/attributes/keys, and output failures report XA4327. Source-link the existing metadata helpers and enable unsafe blocks in the modern task project. Add the pinned ILLink package and its path metadata to the standalone test project, retaining its production-task `ProjectReference`. This layer does not activate the task in MSBuild or change R8 policy. Native-object extraction, orchestration, and legacy cleanup remain in later layers. The copied extractor and fixture exactly match frozen source `87bd3f8a8b512859339e5446c1f86709a6c28c3b`; the test-project native-object metadata is intentionally deferred to layer 4. ## Validation On .NET SDK `11.0.100-preview.7.26381.103`, the following focused standalone run passed **89/89**, with no skips, using the actual modern production task DLL. This includes `RealILLinkRetainsOnlyLiveTypeMapAttributes` with pinned `Microsoft.NET.ILLink.Tasks` `11.0.0-rc.2.26461.115`. ```sh dotnet test tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj -v minimal --filter 'FullyQualifiedName~ExtractTypeMapKeysFromAssembliesTests|FullyQualifiedName~ExtractTypeMapKeysFromLlvmIrArrayTests|FullyQualifiedName~TypeMapProguardTests' ``` Base: `main`. Bottom of native stack #12893.
simonrozsival
added a commit
that referenced
this pull request
Sep 26, 2026
## Why Layer 2 of 4 in native stack #12893, depending on #12824. This adds the NativeAOT representation adapter so typemap-based ProGuard rules can consume the keys retained in the final ILC native object rather than infer retention from a dependency graph. ## Extraction contract - `ExtractTypeMapKeysFromNativeAotObject` reads final relocatable ELF objects using LLVM section/symbol metadata and common-fixup relocations to select the Java type-map groups by their EEType identities. It does not scan arbitrary strings or guess group membership from key appearance. - `NativeAotTypeMapReader` enumerates the selected NativeFormat groups, reusing the existing alias/array normalization and class-name validation helpers. Output is a deterministic union of canonical class keys; invalid required inputs fail with XA4327. - Add the frozen parser/adapter coverage, native-object fixture helpers, tool-path test metadata, and test-catalog instructions. All eight changed files match the frozen #12821 snapshot exactly. ## Tools and scope Extraction requires an existing full path to NDK `llvm-readobj` with adjacent `llvm-objdump`; native test fixtures additionally need adjacent `clang`. Supply `-p:_NativeAotLlvmReadObjPath=/path/to/ndk/bin/llvm-readobj` for native-tool test cases. This layer does **not** activate product targets, add assembly-resolution metadata, expand shared target integration tests, change R8 policy, enable NativeAOT trimming, or retire DGML. The existing DGML pipeline remains active; build activation and policy follow in layers 3 and 4. ## Validation Standalone trimmable typemap project built with .NET 11 preview 7 and `-p:_AndroidTreatWarningsAsErrors=true`, passing the existing NDK tool path. Targeted NativeAOT, linked-DLL, LLVM, ProGuard-generator, typemap-generator, and class-name coverage: **694 passed, 0 failed, 0 skipped**. `NativeAotObjectIntegrationTests.cs` contains shared tool/attribute helpers at this layer; real-object MSBuild integration test methods depend on the later shared target-test expansion and are not claimed as executed here.
simonrozsival
added a commit
that referenced
this pull request
Oct 5, 2026
Complete layer 6 of the frozen #12821 split: activate the shared retained-typemap pipeline, wire R8 retention policies, remove DGML generation, and restore the deferred activation coverage and documentation. Preserve the base XA1037 localization changes. Co-authored-by: Copilot App <[email protected]>
simonrozsival
added a commit
that referenced
this pull request
Oct 6, 2026
Complete layer 6 of the frozen #12821 split: activate the shared retained-typemap pipeline, wire R8 retention policies, remove DGML generation, and restore the deferred activation coverage and documentation. Preserve the base XA1037 localization changes. Co-authored-by: Copilot App <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Why
R8 cannot see managed-to-Java JNI references. Keeping every entry in the
pre-trim ACW map preserves Java classes that managed trimming no longer
needs, while reading Register attributes is not a common representation
for all typemap implementations.
Generate Java class roots from the retained typemap instead, using a small
shared intermediate format and runtime-specific adapters.
Related to #10790, #11767, and #12814.
Implementation
All new tasks live in
Microsoft.Android.Build.Tasks, under theMicrosoft.Android.Tasksnamespace..llJava-name blobsAdapters emit ordinal-sorted, distinct JNI class names, one per line,
UTF-8 without a BOM, with LF endings. Representation-specific aliases and
array keys are normalized before producing the shared class-name file.
Missing or malformed required inputs fail rather than silently producing
an empty retention policy.
<GenerateTypeMapProguardConfiguration/>emits class-only keep rules.Separate configuration handles runtime bootstrap roots and member
preservation. CoreCLR keeps all members of retained JNI-facing classes;
Java-only dependencies remain eligible for member shrinking. NativeAOT
retains the conservative all-members policy. There is no precise
JNI-method inference or runtime obfuscation work here.
The pipeline runs after the relevant trimming/typemap producer and before
R8. Exact per-RID producer paths are propagated and unioned; source-list
and property changes, deleted outputs, incremental builds and Clean are
covered.
NativeAOT no longer generates or scans DGML graphs for this purpose. Its
object adapter currently requires NDK LLVM tools and is explicitly opt-in.
The private
$(_AndroidEnableTypemapR8Trimming)override disables orselects the new pipeline; supported trimmed CoreCLR R8 builds use it
automatically when the override is unset. Complete
$(ProguardConfigFiles)overrides retain their existing behavior.The active CoreCLR path enables R8 optimization while keeping obfuscation
disabled. Other runtime paths retain their configuration selection.
Validation
including real NDK object fixtures, linked-assembly extraction, emitted
LLVM layouts, shared rule generation and MSBuild incremental contracts.
dotnet new androidand MAUIsample-content applications on ARM64, including Samsung A16 runs for
both CoreCLR typemaps and NativeAOT with trimmable typemaps.
applicable. Benchmark/profile artifacts and the reverted precise-member
proof of concept are not part of this PR.
For MAUI sample-content with full managed trimming, Release/ARM64 and
obfuscation disabled, total uncompressed DEX sizes were:
CoreCLR comparisons include enabling R8 optimization. With optimization
disabled on both sides, the respective DEX reductions were 3.85% and
0.086%; the NativeAOT reduction remained 42.70%. The Java-policy toggle
did not materially improve startup with matching MIBC profiles already
applied; this is principally a size improvement.
The MAUI template used the same compatible preview6 dependency pin on both
sides because its original preview7 dependencies produced CS1705 against
the locally built SDK. Trimming warnings were not suppressed.
NativeAOT/full sample-content builds retain a Dashboard-loading limitation
with both rule policies; this PR does not claim to fix it.
Scope and review organization
Visual Studio 2026 provides the supported hosting for these .NET tasks.
Standalone .NET Framework CLI MSBuild is outside the support scope; it is
not a readiness blocker for this change.
NativeAOT remains opt-in until the native-object tooling can be supplied
without requiring an NDK. NativeAOT with the LLVM typemap is unsupported
and is excluded from the results.
This changeset is being split into a stack of smaller review units. This
source PR will remain open until the replacement stack is complete and
verified.