Skip to content

[Xamarin.Android.Build.Tasks] Skip library proguard.txt with disallowed global options#11709

Open
jonathanpeppers wants to merge 2 commits into
mainfrom
jonathanpeppers-vigilant-funicular
Open

[Xamarin.Android.Build.Tasks] Skip library proguard.txt with disallowed global options#11709
jonathanpeppers wants to merge 2 commits into
mainfrom
jonathanpeppers-vigilant-funicular

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Fixes/aligns with the behavior introduced in Android Gradle Plugin 9.0:

From AGP 9.0, Android library and feature module publishing will fail if consumer keep files contain problematic Proguard configurations. Consumer keep files that include global options like -dontoptimize or -dontobfuscate should only be used in application modules, and can reduce optimization benefits for library users. Android App module compilation will silently ignore any such global options if embedded in a pre-compiled dependency (JAR or AAR).

The same restriction applies to R8 for options that control where build outputs go — -printmapping, -printconfiguration, -printusage, -printseeds, -dump. When a third-party .aar (or NuGet package wrapping one) ships a proguard.txt with one of those directives, current dotnet build either:

  • fails the R8 invocation, or
  • writes mapping/usage files to the path the library author chose (silently overwriting the location the app project requested).

Change

In R8.cs, after ResolveLibraryProjectImports has extracted each .aar's proguard.txt, scan the file (only for items that carry the OriginalFile metadata — i.e. library-provided files, not ones we generate or the user added). If any disallowed global option is present:

  • the whole file is skipped — it is not passed to R8 with --pg-conf, and
  • a new XA4322 warning is emitted naming the source: NuGet package id + version when available, otherwise the .aar path.

Example warning:

warning XA4322: Skipping library ProGuard configuration file 'obj/Debug/net10.0-android/lp/0/jl/proguard.txt' (from NuGet package 'Acme.SomeLibrary' 1.2.3) because it contains the unsupported global option '-printmapping'. Global ProGuard options are only allowed in application projects.

User-authored <ProguardConfiguration Include="..." /> items in the app project, and the SDK-generated configs (proguard_xamarin.cfg, proguard_project_primary.cfg, etc.) are left untouched.

Notes

  • The ProguardConfigurationFiles parameter on the R8 task changed from string[] to ITaskItem[] so we can read the OriginalFile/NuGetPackageId/NuGetPackageVersion metadata that ResolveLibraryProjectImports already attaches. No targets needed updating — @(_ProguardConfiguration) / @(ProguardConfiguration) already flow through as items.
  • This is more aggressive than AGP, which silently strips just the offending lines. The simpler "skip whole file + warn" was preferred over rewriting library files to a temp location. The XA4322 doc page describes the workaround (add equivalent -keep rules to the app's own ProguardConfiguration) for users blocked on a 3rd-party library fix.

Tests

  • New R8Tests.TryGetDisallowedOption parametric unit test covers each option, leading whitespace (spaces and tabs), comments, empty lines, and case-insensitive matching.
  • Manual end-to-end verification can be done by adding -printmapping out.txt to any AAR's proguard.txt and observing the XA4322 warning instead of the build failure / silent mapping override.

…ed global options

Android Gradle Plugin 9.0 disallows `global'' ProGuard options such as -printmapping, -printconfiguration, -printusage, -printseeds, and -dump in consumer keep files shipped inside an .aar. AGP either fails library publishing or silently strips the options when consuming a pre-built dependency:

https://developer.android.com/build/releases/agp-9-0-0-release-notes#behavior-changes

Bring the same protection to .NET for Android: when an .aar's proguard.txt (extracted by ResolveLibraryProjectImports) contains one of these options, skip the whole file when invoking R8 and emit a new XA4322 warning naming the NuGet package (or .aar path) the configuration came from. Files generated by us or added directly by the user are untouched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers marked this pull request as ready for review June 22, 2026 17:14
Copilot AI review requested due to automatic review settings June 22, 2026 17:14

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.

Pull request overview

This PR updates the R8 MSBuild task to align with AGP 9.0 behavior by detecting and skipping library-provided proguard.txt files that contain disallowed global ProGuard options, emitting a new XA4322 warning to keep builds reliable and avoid unintended output redirection.

Changes:

  • Change R8.ProguardConfigurationFiles from string[] to ITaskItem[] so metadata (OriginalFile, NuGetPackageId, NuGetPackageVersion) can be used to identify library-provided configs.
  • Add scanning logic in R8.cs to skip offending library proguard.txt files and log XA4322.
  • Add XA4322 resources + documentation, and a unit test for option detection.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/R8Tests.cs Adds unit tests for TryGetDisallowedOption parsing.
src/Xamarin.Android.Build.Tasks/Tasks/R8.cs Implements library proguard option detection + warning emission; switches config input to ITaskItem[].
src/Xamarin.Android.Build.Tasks/Properties/Resources.resx Adds localized message text for XA4322.
src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs Adds generated accessor for XA4322.
Documentation/docs-mobile/messages/xa4322.md Adds a new warning documentation page for XA4322.
Documentation/docs-mobile/messages/index.md Adds XA4322 to the messages index.
Files not reviewed (1)
  • src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file

Comment thread src/Xamarin.Android.Build.Tasks/Tasks/R8.cs
Comment thread src/Xamarin.Android.Build.Tasks/Tasks/R8.cs
Comment thread Documentation/docs-mobile/messages/xa4322.md
…heck

Per the AGP 9.0 release notes, the primary global options called out are -dontoptimize and -dontobfuscate. Add them to DisallowedLibraryProguardOptions so libraries cannot silently disable optimization/obfuscation for consuming apps.

Also tighten TryGetDisallowedOption to require an end-of-token boundary (end-of-line or whitespace) after the matched option, so e.g. '-printmappingFoo' is no longer wrongly treated as '-printmapping'. Tests cover both new options and the boundary case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants