bazelbuild / bazelbuild/rules_android

android_binary doesn't configure ProGuard/R8 for Android?

Open
#308 4 comments 1 reaction 0 assignees View on GitHub
P2
Dominant language
Java
Stars
203
Forks
95
PR merge metrics
No merged PRs in 30d

Description

Hi, wonderful Bazel folks,

This issue is about ProGuard/R8 for `android_binary`, requiring also a minor change to the `android_sdk_repository` rule. I think it's probably more bug than feature request. If I'm right, I'm guessing the fix shouldn't take too much time.

The issue itself: It looks like android_binary might be forgetting to configure its ProGuard invocation for Android by not including the default Android configuration.

Background: For ProGuard/R8 to work properly for Android, one is supposed to supply the default Android ProGuard configuration file so things are set up to work properly. (For more, see https://developer.android.com/studio/build/shrink-code). I was looking closely at all this because I was building an extension to build, ProGuard, and distribute aars, which would solve bazelbuild/rules_android#323. That meant I was reading the Android docs and looking at android_binary as a reference.

Evidence that makes me think Bazel isn't supplying this important configuration file:
- In the Bazel source, I don't see any reference to the default Android configurations, (neither proguard-android.txt nor proguard-android-optimize.txt).
- Running a Bazel build with an empty ProGuard configuration strips everything, rather than preserving things protected by android.support.annotation.Keep, or other key things protected by those default files.
- Dumping the ProGuard command with, e.g. `bazel aquery "mnemonic('Proguard',deps(//:android_binary_target))"`, and examining the specs used didn't show any indication of using the Android configuration files.
- The Android configurations don't seem to be made accessible from `android_sdk_repository`.

Expected behavior would be `android_binary` correctly, automatically configuring ProGuard/R8 for Android when it runs ProGuard. Or at least having android_sdk_repository expose the specs needed to manually do so.

Suggested fix:
1. Export the default ProGuard configuration files from the android SDK.
1. Like proguard, these used to be directly available in the SDK (under tool/proguard/), but that's long deprecated in favor of having the gradle plugin generate them on the fly.
See https://android.googlesource.com/platform/tools/base/+/refs/heads/mirror-goog-studio-main/build-system/gradle-core/src/main/java/com/android/build/gradle/ProguardFiles.java
I don't see a good way of accessing that code through the SDK (I see neither gradle nor that class in a grep of the SDK's jars), so sadly, we'll probably need to bundle them separately, as Bazel does with ProGuard.
3. Whenever ProGuard/R8 runs, additionally supplying `@androidsdk//:tools/proguard/proguard-android-optimize.txt` for opt builds and `@androidsdk//:tools/proguard/proguard-android.txt` otherwise, just as an additional private attribute, and automatically added to the ProGuard configurations on the command line.
1. Offhand I wonder whether ProGuard should really be getting run in dbg or fastbuild modes, but that's a separable thing...

Thanks!
Chris
(ex-Googler)

P.S. All testing was on bazel rolling, 6.0.0-pre.20220208.2.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.