Skip to content

[release/10.0.1xx] [r8] Include build metadata in app bundles - #12669

Open
jonathanpeppers wants to merge 1 commit into
release/10.0.1xxfrom
jonathanpeppers-backport-b4f3cd0-10-0-1xx
Open

[release/10.0.1xx] [r8] Include build metadata in app bundles#12669
jonathanpeppers wants to merge 1 commit into
release/10.0.1xxfrom
jonathanpeppers-backport-b4f3cd0-10-0-1xx

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Backport of #12646 / b4f3cd0 to release/10.0.1xx.

The conflict resolution preserves the release branch's existing R8 task property type and test runtime shape while applying the build-metadata behavior unchanged.

- pass `--build-metadata-output` to R8
- include the generated metadata at `BUNDLE-METADATA/com.android.tools/r8.json` in app bundles
- verify both R8 metadata files are packaged and incremental builds remain up to date

This metadata lets Google Play report R8 optimization, shrinking, and obfuscation coverage for the upcoming app-quality requirements announced in [App quality: Memory optimization and secure onboarding](https://android-developers.googleblog.com/2026/08/app-quality-memory-optimization-secure-onboarding.html).

Related to #12639.
Related to #12535.

Save the following as `Directory.Build.targets` beside the project. It enables R8 for Release builds, downloads R8 9.0.32, generates `r8.json`, and includes it in the app bundle.

The response file is required for this workaround because the shipping .NET 10 task passes `$(AndroidR8ExtraArguments)` directly on the Java command line, with platform-dependent handling of multiple arguments.

```xml
<Project>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <AndroidLinkTool>r8</AndroidLinkTool>
  </PropertyGroup>

  <Target
      Name="IncludeR8BuildMetadata"
      BeforeTargets="_CompileToDalvik"
      Condition=" '$(AndroidLinkTool)' == 'r8' ">
    <PropertyGroup>
      <_R8BuildMetadataFile>$(IntermediateOutputPath)r8.json</_R8BuildMetadataFile>
      <_R8JarFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)r8-9.0.32.jar'))</_R8JarFile>
      <_R8MetadataRsp>$(IntermediateOutputPath)r8-build-metadata.rsp</_R8MetadataRsp>
      <AndroidR8JarPath>$(_R8JarFile)</AndroidR8JarPath>
      <AndroidR8ExtraArguments>@$(_R8MetadataRsp)</AndroidR8ExtraArguments>
    </PropertyGroup>

    <DownloadFile
        Condition=" !Exists('$(_R8JarFile)') "
        SourceUrl="https://storage.googleapis.com/r8-releases/raw/9.0.32/r8.jar"
        DestinationFolder="$(IntermediateOutputPath)"
        DestinationFileName="r8-9.0.32.jar"
    />
    <WriteLinesToFile
        File="$(_R8MetadataRsp)"
        Overwrite="true"
        Lines="--build-metadata-output;$(_R8BuildMetadataFile)"
    />

    <ItemGroup>
      <AndroidAppBundleMetaDataFile Include="com.android.tools/r8.json:$(_R8BuildMetadataFile)" />
    </ItemGroup>
  </Target>
</Project>
```

Build the app bundle with:

```console
dotnet build -c Release -p:AndroidPackageFormat=aab
```

The resulting signed AAB should contain `BUNDLE-METADATA/com.android.tools/r8.json`. This workaround was verified on macOS by @yuseok-kim-edushare and end-to-end on Windows with the .NET 10 Android workload: the metadata reports R8 9.0.32 and its DEX SHA-256 matches the packaged `classes.dex`.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit b4f3cd0)
Copilot-Session: 459f8db0-c8d7-4c77-99ea-3d43dd9f57d8
Copilot AI lite review requested due to automatic review settings September 3, 2026 19:20
@jonathanpeppers
jonathanpeppers changed the base branch from main to release/10.0.1xx September 3, 2026 19:21
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
1 pipeline(s) were filtered out due to trigger conditions.

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.

🟢 Approval recommended

The changes are narrowly scoped, match existing MSBuild/task patterns, and include a targeted test asserting both packaging correctness and incremental behavior.

Pull request overview

This PR backports the upstream change to generate and package R8 build metadata into Android App Bundles (AAB) on the release/10.0.1xx branch, enabling Google Play to report R8 optimization/shrinking/obfuscation coverage.

Changes:

  • Pass --build-metadata-output <path> to the R8 task so it emits r8.json into the intermediate output.
  • Include the generated r8.json as BUNDLE-METADATA/com.android.tools/r8.json when building app bundles.
  • Extend packaging tests to verify both metadata files are present in the signed AAB and that incremental builds remain up-to-date.
File summaries
File Description
src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets Wires the new BuildMetadataFileOutput parameter into the R8 task invocation and tracks the generated file in FileWrites.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Defines the intermediate r8.json path and adds it to AndroidAppBundleMetaDataFile so bundletool packages it into BUNDLE-METADATA/.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs Updates/extends the packaging test to validate proguard.map and r8.json are inside the signed AAB and that key targets are skipped on a no-op rebuild.
src/Xamarin.Android.Build.Tasks/Tasks/R8.cs Adds a task property and appends --build-metadata-output to the R8 response file when configured.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants