Skip to content

[Microsoft.Android.Build.Tasks] Generate typemap ProGuard rules - #12821

Closed
simonrozsival wants to merge 25 commits into
mainfrom
simonrozsival-trimmed-typemap-proguard
Closed

simonrozsival wants to merge 25 commits into
mainfrom
simonrozsival-trimmed-typemap-proguard

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

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 the
Microsoft.Android.Tasks namespace.

Runtime / typemap Retained-key adapter input
CoreCLR / LLVM IR Generated .ll Java-name blobs
CoreCLR / trimmable Linked typemap DLLs and surviving TypeMap attributes
NativeAOT / trimmable Final ILC native objects, selecting Java typemap groups through their fixups

Adapters 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 or
selects 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

  • 421 focused tests passed with warnings treated as errors and no skips,
    including real NDK object fixtures, linked-assembly extraction, emitted
    LLVM layouts, shared rule generation and MSBuild incremental contracts.
  • Built, installed and launched stock dotnet new android and MAUI
    sample-content applications on ARM64, including Samsung A16 runs for
    both CoreCLR typemaps and NativeAOT with trimmable typemaps.
  • Repeated startup comparisons used matching MIBC profiles where
    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:

Runtime / typemap Legacy rules Retained-typemap pipeline
CoreCLR / LLVM IR 4,876,916 bytes 3,314,404 bytes
CoreCLR / trimmable 4,564,308 bytes 3,186,728 bytes
NativeAOT / trimmable 13,070,696 bytes 7,489,768 bytes

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.

simonrozsival and others added 25 commits September 18, 2026 09:03
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]>
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]>
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]>
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]>
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]>
@simonrozsival
simonrozsival marked this pull request as ready for review September 18, 2026 14:47
Copilot AI lite review requested due to automatic review settings September 18, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 Medium severity

Open (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)">
@simonrozsival simonrozsival added the r8-rules Typemap-derived ProGuard and R8 rules label 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r8-rules Typemap-derived ProGuard and R8 rules

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants