Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions rules/aar_import/impl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,9 @@ def _collect_proguard(
aar,
aar_embedded_proguard_extractor):
args = ctx.actions.args()
args.add("--input_aar", aar)
args.add("--input_archive", aar)
args.add("--output_proguard_file", out_proguard)
args.add("--archive_type", "aar")
ctx.actions.run(
executable = aar_embedded_proguard_extractor,
arguments = [args],
Expand Down Expand Up @@ -565,7 +566,7 @@ def impl(ctx):
ctx,
proguard_spec,
aar,
_get_android_toolchain(ctx).aar_embedded_proguard_extractor.files_to_run,
_get_android_toolchain(ctx).archive_embedded_proguard_extractor.files_to_run,
))

lint_providers = _process_lint_rules(
Expand Down
19 changes: 18 additions & 1 deletion rules/android_binary/r8.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,25 @@ def process_r8(ctx, validation_ctx, jvm_ctx, packaged_resources_ctx, build_info_
dexes_zip = ctx.actions.declare_file(ctx.label.name + "_dexes.zip")
proguard_mappings_output_file = ctx.actions.declare_file(ctx.label.name + "_proguard.map")

# Extract proguard specs embedded in the deploy JAR (META-INF/proguard/
# and META-INF/com.android.tools/) so they are passed to R8.
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_archive", deploy_jar)
jar_extractor_args.add("--output_proguard_file", jar_embedded_proguard)
jar_extractor_args.add("--archive_type", "jar")
ctx.actions.run(
executable = get_android_toolchain(ctx).archive_embedded_proguard_extractor.files_to_run,
arguments = [jar_extractor_args],
inputs = [deploy_jar],
outputs = [jar_embedded_proguard],
mnemonic = "JarEmbeddedProguardExtractor",
progress_message = "Extracting proguard specs from deploy jar for %{label}",
toolchain = None,
)

android_jar = get_android_sdk(ctx).android_jar
proguard_specs = proguard.get_proguard_specs(ctx, packaged_resources_ctx.resource_proguard_config)
proguard_specs = proguard.get_proguard_specs(ctx, packaged_resources_ctx.resource_proguard_config) + [jar_embedded_proguard]

# Get min SDK version from attribute, manifest_values, or depot floor
effective_min_sdk = min_sdk_version.DEPOT_FLOOR
Expand Down
4 changes: 2 additions & 2 deletions toolchains/android/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ _ATTRS = dict(
default = "//tools/android:aar_embedded_jars_extractor",
executable = True,
),
aar_embedded_proguard_extractor = attr.label(
archive_embedded_proguard_extractor = attr.label(
allow_files = True,
cfg = "exec",
default = "//tools/android:aar_embedded_proguard_extractor",
default = "//tools/android:archive_embedded_proguard_extractor",
executable = True,
),
aar_native_libs_zip_creator = attr.label(
Expand Down
10 changes: 5 additions & 5 deletions tools/android/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,8 @@ py_binary(
)

py_binary(
name = "aar_embedded_proguard_extractor",
srcs = ["aar_embedded_proguard_extractor.py"],
name = "archive_embedded_proguard_extractor",
srcs = ["archive_embedded_proguard_extractor.py"],
visibility = ["//visibility:public"],
deps = [
":json_worker_wrapper",
Expand Down Expand Up @@ -474,9 +474,9 @@ py_test(
)

py_test(
name = "aar_embedded_proguard_extractor_test",
srcs = ["aar_embedded_proguard_extractor_test.py"],
deps = [":aar_embedded_proguard_extractor"],
name = "archive_embedded_proguard_extractor_test",
srcs = ["archive_embedded_proguard_extractor_test.py"],
deps = [":archive_embedded_proguard_extractor"],
)

py_test(
Expand Down
74 changes: 0 additions & 74 deletions tools/android/aar_embedded_proguard_extractor.py

This file was deleted.

54 changes: 0 additions & 54 deletions tools/android/aar_embedded_proguard_extractor_test.py

This file was deleted.

109 changes: 109 additions & 0 deletions tools/android/archive_embedded_proguard_extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# pylint: disable=g-direct-third-party-import
# Copyright 2021 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A tool for extracting proguard spec files from a JAR or AAR."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import io
import os
import zipfile

# Do not edit this line. Copybara replaces it with PY2 migration helper.
from absl import app
from absl import flags

from tools.android import json_worker_wrapper
from tools.android import junction

FLAGS = flags.FLAGS

flags.DEFINE_string("input_archive", None, "Input JAR or AAR")
flags.mark_flag_as_required("input_archive")
flags.DEFINE_string("output_proguard_file", None,
"Output parameter file for proguard")
flags.mark_flag_as_required("output_proguard_file")
flags.DEFINE_enum("archive_type", None, ["jar", "aar"],
"Type of archive: jar or aar")
flags.mark_flag_as_required("archive_type")


def _ExtractR8Rules(jar, output):
"""Extract R8 rules from META-INF/com.android.tools/ inside a JAR.

Handles subdirectories like r8-from-X-upto-Y/. All matching files are
concatenated into the output, sorted by path for determinism.
"""
meta_inf_prefix = "META-INF/com.android.tools/"
for entry in sorted(jar.namelist()):
if entry.startswith(meta_inf_prefix) and not entry.endswith("/"):
output.write(b"\n")
output.write(jar.read(entry))


def ExtractEmbeddedProguardFromJar(jar, output):
"""Extract proguard specs from a JAR file."""
legacy_prefix = "META-INF/proguard/"
r8_prefix = "META-INF/com.android.tools/"

for entry in sorted(jar.namelist()):
if not entry.endswith("/") and (
entry.startswith(legacy_prefix) or entry.startswith(r8_prefix)):
output.write(b"\n")
output.write(jar.read(entry))


def ExtractEmbeddedProguardFromAar(aar, output):
"""Extract proguard specs from an AAR file."""
proguard_spec = "proguard.txt"
classes_jar = "classes.jar"

if proguard_spec in aar.namelist():
output.write(aar.read(proguard_spec))

# For AARs, META-INF/com.android.tools/ lives inside classes.jar
if classes_jar in aar.namelist():
with zipfile.ZipFile(io.BytesIO(aar.read(classes_jar)), "r") as jar:
_ExtractR8Rules(jar, output)


def _Main(input_archive, output_proguard_file, archive_type):
with zipfile.ZipFile(input_archive, "r") as archive:
with open(output_proguard_file, "wb") as output:
if archive_type == "jar":
ExtractEmbeddedProguardFromJar(archive, output)
else:
ExtractEmbeddedProguardFromAar(archive, output)


def main(unused_argv):
if os.name == "nt":
archive_long = os.path.abspath(FLAGS.input_archive)
proguard_long = os.path.abspath(FLAGS.output_proguard_file)

with junction.TempJunction(os.path.dirname(archive_long)) as archive_junc:
with junction.TempJunction(
os.path.dirname(proguard_long)) as proguard_junc:
_Main(
os.path.join(archive_junc, os.path.basename(archive_long)),
os.path.join(proguard_junc, os.path.basename(proguard_long)),
FLAGS.archive_type)
else:
_Main(FLAGS.input_archive, FLAGS.output_proguard_file, FLAGS.archive_type)


if __name__ == "__main__":
json_worker_wrapper.wrap_worker(FLAGS, main, app.run)
Loading