Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Extract r8 rules based on version #511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
snazhmudinov wants to merge 9 commits into bazelbuild:main
base: main
Choose a base branch
Loading
from snazhmudinov:extract-r8-rules-based-on-ver
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
9 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions rules/android_binary/r8.bzl
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,16 @@ def process_r8(ctx, validation_ctx, jvm_ctx, packaged_resources_ctx, build_info_
# The deploy jar from the deploy_jar processor is not used because as of now, whether it
# actually produces a deploy jar is determinted by a separate set of ACLs, and also does
# desugaring differently than with R8.
runtime_jars = depset(
direct = jvm_ctx.java_info.runtime_output_jars + [packaged_resources_ctx.class_jar],
transitive = [jvm_ctx.java_info.transitive_runtime_jars],
)

deploy_jar = ctx.actions.declare_file(ctx.label.name + "_deploy.jar")
java.create_deploy_jar(
ctx,
output = deploy_jar,
runtime_jars = depset(
direct = jvm_ctx.java_info.runtime_output_jars + [packaged_resources_ctx.class_jar],
transitive = [jvm_ctx.java_info.transitive_runtime_jars],
),
runtime_jars = runtime_jars,
java_toolchain = common.get_java_toolchain(ctx),
build_target = ctx.label.name,
deploy_manifest_lines = build_info_ctx.deploy_manifest_lines,
Expand All @@ -84,20 +86,21 @@ def process_r8(ctx, validation_ctx, jvm_ctx, packaged_resources_ctx, build_info_
proguard_specs = proguard.get_proguard_specs(ctx, packaged_resources_ctx.resource_proguard_config)
desugared_lib_config = ctx.file._desugared_lib_config

# Optionally extract proguard specs embedded in the deploy JAR (META-INF/proguard/
# and META-INF/com.android.tools/) so they are passed to R8.
# Optionally extract proguard specs embedded in runtime JARs (META-INF/proguard/
# and META-INF/com.android.tools/) so they are passed to R8. Each JAR is processed
# independently to avoid META-INF clobbering from the deploy JAR merge.
if _flags.get(ctx).r8_extract_embedded_proguard_specs:
jar_embedded_proguard = ctx.actions.declare_file(ctx.label.name + "_jar_embedded_proguard.pro")
jar_extractor_args = ctx.actions.args()
jar_extractor_args.add("--input_jar", deploy_jar)
jar_extractor_args.add_all("--input_jars", runtime_jars)
jar_extractor_args.add("--output_proguard_file", jar_embedded_proguard)
ctx.actions.run(
executable = get_android_toolchain(ctx).jar_embedded_proguard_extractor.files_to_run,
arguments = [jar_extractor_args],
inputs = [deploy_jar],
inputs = runtime_jars,
outputs = [jar_embedded_proguard],
mnemonic = "JarEmbeddedProguardExtractor",
progress_message = "Extracting proguard specs from deploy jar for %{label}",
progress_message = "Extracting proguard specs from runtime jars for %{label}",
toolchain = None,
)
proguard_specs = proguard_specs + [jar_embedded_proguard]
Expand Down
20 changes: 20 additions & 0 deletions tools/android/BUILD
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ java_binary(
runtime_deps = ["@rules_android_maven//:com_android_tools_r8"],
)

java_binary(
name = "r8_version_bin",
srcs = ["R8Version.java"],
main_class = "tools.android.R8Version",
deps = ["@rules_android_maven//:com_android_tools_r8"],
)

java_binary(
name = "tracereferences",
jvm_flags = _JVM_FLAGS,
Expand Down Expand Up @@ -435,23 +442,27 @@ py_library(
py_binary(
name = "aar_embedded_proguard_extractor",
srcs = ["aar_embedded_proguard_extractor.py"],
data = [":r8_version"],
visibility = ["//visibility:public"],
deps = [
":json_worker_wrapper",
":junction_lib",
":proguard_extractor_lib",
"@bazel_tools//tools/python/runfiles",
"@py_absl//absl:app",
],
)

py_binary(
name = "jar_embedded_proguard_extractor",
srcs = ["jar_embedded_proguard_extractor.py"],
data = [":r8_version"],
visibility = ["//visibility:public"],
deps = [
":json_worker_wrapper",
":junction_lib",
":proguard_extractor_lib",
"@bazel_tools//tools/python/runfiles",
"@py_absl//absl:app",
],
)
Expand Down Expand Up @@ -660,3 +671,12 @@ genrule(
""",
visibility = ["//visibility:public"],
)

genrule(
name = "r8_version",
outs = [
"r8.version",
],
cmd = "$(location :r8_version_bin) >$(OUTS)",
tools = [":r8_version_bin"],
)
7 changes: 7 additions & 0 deletions tools/android/R8Version.java
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tools.android;

public class R8Version {
public static void main(String[] args) {
System.out.println(com.android.tools.r8.Version.LABEL);
}
}
26 changes: 13 additions & 13 deletions tools/android/aar_embedded_proguard_extractor.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from __future__ import division
from __future__ import print_function

from bazel_tools.tools.python.runfiles import runfiles

import os
import zipfile

Expand All @@ -41,22 +43,20 @@
)


# Attempt to extract proguard spec from AAR. If the file doesn't exist, an empty
# proguard spec file will be created
def ExtractEmbeddedProguard(aar, output, extract_r8_rules=False):
if extract_r8_rules:
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, output)
else:
proguard_extractor_lib.ExtractEmbeddedProguardFromAarLegacy(aar, output)


def _Main(input_aar, output_proguard_file, extract_r8_rules):
def _Main(input_aar, output_proguard_file, r8_version = None):
with zipfile.ZipFile(input_aar, "r") as aar:
with open(output_proguard_file, "wb") as output:
ExtractEmbeddedProguard(aar, output, extract_r8_rules)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, output, r8_version)


def main(unused_argv):
r = runfiles.Create()
r8_version = None
with open(r.Rlocation("rules_android/tools/android/r8.version"), "r") as file:
runfile_lines = file.readlines()
if runfile_lines:
r8_version = runfile_lines[0].strip()

if os.name == "nt":
# Shorten paths unconditionally, because the extracted paths in
# ExtractEmbeddedJars (which we cannot yet predict, because they depend on
Expand All @@ -70,10 +70,10 @@ def main(unused_argv):
_Main(
os.path.join(aar_junc, os.path.basename(aar_long)),
os.path.join(proguard_junc, os.path.basename(proguard_long)),
FLAGS.extract_r8_rules,
r8_version
)
else:
_Main(FLAGS.input_aar, FLAGS.output_proguard_file, FLAGS.extract_r8_rules)
_Main(FLAGS.input_aar, FLAGS.output_proguard_file, r8_version)


if __name__ == "__main__":
Expand Down
121 changes: 42 additions & 79 deletions tools/android/aar_embedded_proguard_extractor_test.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -18,59 +18,14 @@
import unittest
import zipfile

from tools.android import aar_embedded_proguard_extractor
from tools.android import proguard_extractor_lib


class AarEmbeddedProguardExtractorLegacyTest(unittest.TestCase):
"""Unit tests for AAR proguard extraction.

Legacy behavior, i.e. extract_r8_rules=False.
"""
class AarEmbeddedProguardExtractorTest(unittest.TestCase):
"""Unit tests for AAR proguard extraction."""

def setUp(self):
super(AarEmbeddedProguardExtractorLegacyTest, self).setUp()
os.chdir(os.environ["TEST_TMPDIR"])

def testNoProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
proguard_file = io.BytesIO()
aar_embedded_proguard_extractor.ExtractEmbeddedProguard(aar, proguard_file)
proguard_file.seek(0)
self.assertEqual(b"", proguard_file.read())

def testWithProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("proguard.txt", "hello world")
proguard_file = io.BytesIO()
aar_embedded_proguard_extractor.ExtractEmbeddedProguard(aar, proguard_file)
proguard_file.seek(0)
self.assertEqual(b"hello world", proguard_file.read())

def make_classes_jar(self, entries):
jar_buf = io.BytesIO()
with zipfile.ZipFile(jar_buf, "w") as jar:
for path, content in entries.items():
jar.writestr(path, content)
return jar_buf.getvalue()

def testR8RulesFromClassesJarIgnoredByDefault(self):
classes_jar = self.make_classes_jar({
"META-INF/com.android.tools/r8/rules.pro": "-keep class A",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
aar_embedded_proguard_extractor.ExtractEmbeddedProguard(aar, proguard_file)
proguard_file.seek(0)
self.assertEqual(b"", proguard_file.read())


class AarEmbeddedProguardExtractorWithR8RulesTest(unittest.TestCase):
"""Unit tests for AAR proguard extraction with extract_r8_rules=True."""

def setUp(self):
super(AarEmbeddedProguardExtractorWithR8RulesTest, self).setUp()
super(AarEmbeddedProguardExtractorTest, self).setUp()
os.chdir(os.environ["TEST_TMPDIR"])

def make_classes_jar(self, entries):
Expand All @@ -83,82 +38,90 @@ def make_classes_jar(self, entries):
def testNoProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"", proguard_file.read())

def testWithProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("proguard.txt", "hello world")
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"hello world", proguard_file.read())

def testR8RulesFromClassesJar(self):
def testTargetedR8RulesFromClassesJar(self):
classes_jar = self.make_classes_jar({
"META-INF/com.android.tools/r8/rules.pro": "-keep class A",
"META-INF/com.android.tools/r8-from-8.0.0-upto-9.0.0/rules.pro": "-keep class A",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"\n-keep class A", proguard_file.read())

def testR8RulesFromVersionedSubdirs(self):
def testTargetedR8RulesPreferredOverProguardTxt(self):
classes_jar = self.make_classes_jar({
"META-INF/com.android.tools/r8-from-8.0.0/rules.pro": "-keep class B",
"META-INF/com.android.tools/r8-upto-8.0.0/rules.pro": "-keep class C",
"META-INF/com.android.tools/r8-from-8.0.0-upto-9.0.0/rules.pro": "-keep class targeted",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("proguard.txt", "-keep class legacy")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"\n-keep class B\n-keep class C", proguard_file.read())
self.assertEqual(b"\n-keep class targeted", proguard_file.read())

def testR8RulesAndProguardTxtCombined(self):
def testFallsBackToProguardTxtWhenNoVersionMatch(self):
classes_jar = self.make_classes_jar({
"META-INF/com.android.tools/r8/rules.pro": "-keep class D",
"META-INF/com.android.tools/r8-from-1.0.0-upto-2.0.0/rules.pro": "-keep class old",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("proguard.txt", "-keep class E")
aar.writestr("proguard.txt", "-keep class legacy")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"-keep class E\n-keep class D", proguard_file.read())
self.assertEqual(b"-keep class legacy", proguard_file.read())

def testR8RulesIgnoresDirectoryEntries(self):
classes_jar = self.make_classes_jar({
"META-INF/com.android.tools/": "",
"META-INF/com.android.tools/r8/": "",
"META-INF/com.android.tools/r8/rules.pro": "-keep class F",
})
def testNoClassesJarFallsBackToProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("classes.jar", classes_jar)
aar.writestr("proguard.txt", "-keep class legacy")
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"\n-keep class F", proguard_file.read())
self.assertEqual(b"-keep class legacy", proguard_file.read())

def testNoClassesJarNoR8Rules(self):
def testClassesJarWithoutR8Rules(self):
classes_jar = self.make_classes_jar({
"com/example/Foo.class": "classdata",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("some_other_file.txt", "data")
aar.writestr("proguard.txt", "-keep class legacy")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"", proguard_file.read())
self.assertEqual(b"-keep class legacy", proguard_file.read())

def testClassesJarWithoutR8Rules(self):
def testNoneR8VersionFallsBackToProguardTxt(self):
classes_jar = self.make_classes_jar({
"com/example/Foo.class": "classdata",
"META-INF/com.android.tools/r8-from-8.0.0-upto-9.0.0/rules.pro": "-keep class targeted",
})
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("proguard.txt", "-keep class legacy")
aar.writestr("classes.jar", classes_jar)
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file)
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, None)
proguard_file.seek(0)
self.assertEqual(b"-keep class legacy", proguard_file.read())

def testNoClassesJarNoProguardTxt(self):
aar = zipfile.ZipFile(io.BytesIO(), "w")
aar.writestr("some_other_file.txt", "data")
proguard_file = io.BytesIO()
proguard_extractor_lib.ExtractEmbeddedProguardFromAar(aar, proguard_file, "8.9.35")
proguard_file.seek(0)
self.assertEqual(b"", proguard_file.read())

Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /