[r8-obfuscation] Enable R8 JNI name obfuscation for CoreCLR - #12632
[r8-obfuscation] Enable R8 JNI name obfuscation for CoreCLR#12632simonrozsival wants to merge 21 commits into
Conversation
bdfec0a to
7c15701
Compare
f51fbae to
f88d2f4
Compare
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
1cee050 to
65740e9
Compare
2f3c599 to
5e41251
Compare
5e41251 to
cbc7457
Compare
cbc7457 to
61d0a23
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
61d0a23 to
ed2522d
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
60b031c to
15c4b79
Compare
Preserve managed constructor spellings, resolve cached static JNI class handles through proven FindClass assignments, warn on unsafe renamed lookup sources, and skip identity string rewrites. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use platform-aware path identity for in-place rewrites, validate custom attribute prologs, and diagnose unsafe member-only mappings without polluting rewrite manifests or reverse scans. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Allow seed R8 to rename ACWs, track final R8 generated inputs, and keep validation mappings private when public mapping output is disabled. Use canonical LF expectations for generated reachability manifests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Build the seed R8 configuration from user and library consumer rules instead of final generated configuration, whose baseline native-method rule pins ACW names. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Generate identity keep rules directly from the merged text manifest so seed R8 does not require resources to be linked early. Keep final AAPT resource rules on their normal late path and cover manifest normalization, provenance, and resource independence.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Assert that an activity alias identity is not treated as a Java class while its target activity remains protected. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Prepare the manifest merger directory before seed manifest rule generation, and keep generated ACW pinning rules out of final JNI-obfuscating R8 passes while retaining final AAPT and mapped reachability rules. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copy the shared trimmable manifest into each inner build before seed manifest merging, and validate final R8 output through its configured public mapping path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Allow blank records when validating generated reachability manifests, and resolve the final AAPT rules through their explicit configuration provenance instead of filesystem name uniqueness. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Convert manifest-style JNI paths to the native directory separator at the filesystem copy boundary. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
15c4b79 to
6a05a22
Compare
|
/review |
|
❌ Android PR Reviewer failed. Please review the logs for details.
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new manifest keep-rule generator currently treats a <process> element as a Java class source, which can produce incorrect keep rules and should be corrected before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
src/Xamarin.Android.Build.Tasks/Tasks/GenerateR8JniManifestProguardConfiguration.cs — ❌ error: The manifest keep-rule generator treats a <process android:name="..."/> element as a Java… |
|
src/Xamarin.Android.Build.Tasks/Tasks/R8.cs — 💡 suggestion: GenerateCommonXamarinConfiguration writes the generated ProGuard config via… |
What changed in this PR
This PR extends the .NET for Android build pipeline to support an opt-in, two-pass R8 workflow that enables JNI name obfuscation for trimmed CoreCLR builds. It introduces seed/final mapping propagation, mapping validation (XA4327), and plumbing for the new mapping/manifests through MSBuild targets and tasks.
Changes:
- Add two-pass R8 seed/final mapping inputs/outputs and validation for JNI name rewriting, including a new XA4327 error code and documentation.
- Introduce manifest-only keep-rule generation for the seed pass, plus additional provenance metadata on ProGuard/R8 configuration items for correct filtering.
- Add/expand unit and integration tests covering mapping validation, reachability manifests, Java source path reverse-mapping, and incrementality.
| File | Description |
|---|---|
| src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets | Wire new mapping input/output + validation inputs into the R8 invocation and FileWrites. |
| src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets | Add property caching, mapping output selection, compile inputs augmentation, and configuration provenance metadata. |
| src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/R8Mapping.cs | Add helper for obfuscated-class presence and ignore empty manifest lines in reachability checks. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/R8MappingTests.cs | Add regression test ensuring reachability manifests can contain empty lines. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs | Add CoreCLR integration coverage for the JNI rewriting pipeline, including incrementality and multi-RID behavior. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/R8Tests.cs | Add focused tests for seed mapping behavior, baseline filtering, ACW keep-rule filtering, and XA4327 validation. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GenerateTrimmableTypeMapTests.cs | Add tests for reverse-mapping obfuscated Java source paths and XA4327 error reporting on conflicts. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GenerateR8JniManifestProguardConfigurationTests.cs | New tests validating deterministic manifest-only keep rules and XA4327 error cases. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GenerateProguardConfigurationTests.cs | New tests validating mapped keep-rule output and reachability manifest generation. |
| src/Xamarin.Android.Build.Tasks/Tasks/R8.cs | Add seed-mapping mode, applymapping support, baseline filtering for JNI obfuscation, and mapping validation plumbing. |
| src/Xamarin.Android.Build.Tasks/Tasks/GenerateTrimmableTypeMap.cs | Add optional R8 mapping + rewrite manifest inputs to reverse-map generated Java source paths back to originals. |
| src/Xamarin.Android.Build.Tasks/Tasks/GenerateR8JniManifestProguardConfiguration.cs | New task to derive seed-pass keep rules from the merged manifest without resource resolution. |
| src/Xamarin.Android.Build.Tasks/Tasks/GenerateProguardConfiguration.cs | Extend to emit allowobfuscation keep rules driven by rewritten-assembly scanning plus reachability manifest output. |
| src/Xamarin.Android.Build.Tasks/Properties/Resources.resx | Add XA4327 and associated detail strings. |
| src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs | Update generated resource accessors for XA4327 strings. |
| src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Aapt2.targets | Mark AAPT-generated rules with metadata to preserve/identify provenance for filtering. |
| src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets | Add seed-pass compilation/mapping targets and shared-output wiring for inner builds. |
| src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets | Ensure proguard config generation participates in dalvik compile deps; add pre-ILLink rewrite stage and extend inputs/outputs. |
| Documentation/docs-mobile/TOC.yml | Add XA4327 doc entry to TOC. |
| Documentation/docs-mobile/messages/xa4327.md | New documentation page for XA4327. |
| Documentation/docs-mobile/messages/index.md | Add XA4327 to the error index list. |
| Documentation/docs-mobile/building-apps/build-properties.md | Document the new AndroidEnableR8JniNameObfuscation property and requirements. |
Files not reviewed (1)
- src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file
| case "provider": | ||
| case "instrumentation": | ||
| case "process": | ||
| AddClass (classes, packageName, element, "name"); | ||
| break; |
| return; | ||
| } | ||
|
|
||
| using var xamcfg = File.CreateText (ProguardCommonXamarinConfiguration); |


Related to #12535
Depends on #12631
Layer 5 of 6 in the replacement stack for #12575. This layer adds the shared two-pass R8 seed/final mapping machinery and enables opt-in JNI name obfuscation for trimmed CoreCLR builds. NativeAOT support follows in layer 6.
Testing:
Xamarin.Android.Build.Tasks.csprojand the completeXamarin.Android.Build.Tests.csproj.GenerateProguardConfiguration/R8task tests, including canonical LF manifest output for the Windows failure in build 1577218.NETSDK1147because the unrelatedwasm-toolsworkload is not installed.