168 lines
6.9 KiB
Python
168 lines
6.9 KiB
Python
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
#
|
|
# This source code is licensed under both the MIT license found in the
|
|
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
|
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
# of this source tree.
|
|
|
|
load("@prelude//android:android_toolchain.bzl", "AndroidToolchainInfo")
|
|
load("@prelude//java:java_toolchain.bzl", "JavaToolchainInfo")
|
|
load("@prelude//java/utils:java_utils.bzl", "get_path_separator")
|
|
load("@prelude//utils:utils.bzl", "expect")
|
|
|
|
_UNSCRUBBED_JARS_DIR = "unscrubbed"
|
|
|
|
ProguardOutput = record(
|
|
jars_to_owners = {"artifact": "target_label"},
|
|
proguard_configuration_output_file = ["artifact", None],
|
|
proguard_mapping_output_file = "artifact",
|
|
proguard_artifacts = ["artifact"],
|
|
)
|
|
|
|
def _get_proguard_command_line_args(
|
|
ctx: "context",
|
|
inputs_to_unscrubbed_outputs: {"artifact": "artifact"},
|
|
proguard_configs: ["artifact"],
|
|
mapping: "artifact",
|
|
configuration: ["artifact", None],
|
|
seeds: ["artifact", None],
|
|
usage: ["artifact", None],
|
|
android_toolchain: "AndroidToolchainInfo") -> "cmd_args":
|
|
cmd = cmd_args()
|
|
cmd.add("-basedirectory", "<user.dir>")
|
|
|
|
android_sdk_proguard_config = ctx.attrs.android_sdk_proguard_config or "none"
|
|
if android_sdk_proguard_config == "optimized":
|
|
cmd.add("-include", android_toolchain.optimized_proguard_config)
|
|
cmd.add("-optimizationpasses", str(ctx.attrs.optimization_passes))
|
|
elif android_sdk_proguard_config == "default":
|
|
cmd.add("-include", android_toolchain.proguard_config)
|
|
else:
|
|
expect(android_sdk_proguard_config == "none")
|
|
|
|
for proguard_config in dedupe(proguard_configs):
|
|
cmd.add("-include")
|
|
cmd.add(cmd_args("\"", proguard_config, "\"", delimiter = ""))
|
|
|
|
for jar_input, jar_output in inputs_to_unscrubbed_outputs.items():
|
|
cmd.add("-injar", jar_input, "-outjar", jar_output if jar_output == jar_input else jar_output.as_output())
|
|
|
|
cmd.add("-library")
|
|
cmd.add(cmd_args(android_toolchain.android_bootclasspath, delimiter = get_path_separator()))
|
|
|
|
cmd.add("-printmapping", mapping.as_output())
|
|
if configuration:
|
|
cmd.add("-printconfiguration", configuration.as_output())
|
|
if seeds:
|
|
cmd.add("-printseeds", seeds.as_output())
|
|
if usage:
|
|
cmd.add("-printusage", usage.as_output())
|
|
|
|
return cmd
|
|
|
|
def run_proguard(
|
|
ctx: "context",
|
|
android_toolchain: "AndroidToolchainInfo",
|
|
java_toolchain: "JavaToolchainInfo",
|
|
command_line_args_file: "artifact",
|
|
command_line_args: "cmd_args",
|
|
mapping_file: "artifact"):
|
|
run_proguard_cmd = cmd_args()
|
|
run_proguard_cmd.add(
|
|
java_toolchain.java[RunInfo],
|
|
"-XX:-MaxFDLimit",
|
|
ctx.attrs.proguard_jvm_args,
|
|
"-Xmx{}".format(android_toolchain.proguard_max_heap_size),
|
|
"-jar",
|
|
android_toolchain.proguard_jar,
|
|
)
|
|
run_proguard_cmd.add(cmd_args(command_line_args_file, format = "@{}"))
|
|
run_proguard_cmd.hidden(command_line_args)
|
|
|
|
# Some proguard configs can propagate the "-dontobfuscate" flag which disables
|
|
# obfuscation and prevents the mapping.txt file from being generated.
|
|
sh_cmd = cmd_args([
|
|
"sh",
|
|
"-c",
|
|
"touch $1 && $2",
|
|
"--",
|
|
mapping_file.as_output(),
|
|
cmd_args(run_proguard_cmd, delimiter = " "),
|
|
])
|
|
|
|
ctx.actions.run(sh_cmd, category = "run_proguard")
|
|
|
|
# Note that ctx.attrs.skip_proguard means that we should create the proguard command line (since
|
|
# e.g. Redex might want to consume it) but we don't actually run the proguard command.
|
|
def get_proguard_output(
|
|
ctx: "context",
|
|
input_jars: {"artifact": "target_label"},
|
|
java_packaging_deps: ["JavaPackagingDep"],
|
|
aapt_generated_proguard_config: ["artifact", None]) -> ProguardOutput.type:
|
|
proguard_configs = [packaging_dep.proguard_config for packaging_dep in java_packaging_deps if packaging_dep.proguard_config]
|
|
if ctx.attrs.proguard_config:
|
|
proguard_configs.append(ctx.attrs.proguard_config)
|
|
if not ctx.attrs.ignore_aapt_proguard_config and aapt_generated_proguard_config:
|
|
proguard_configs.append(aapt_generated_proguard_config)
|
|
|
|
if ctx.attrs.skip_proguard:
|
|
inputs_to_unscrubbed_outputs = {input_jar: input_jar for input_jar in input_jars.keys()}
|
|
mapping = ctx.actions.write("proguard/mapping.txt", [])
|
|
configuration = None
|
|
seeds = None
|
|
usage = None
|
|
else:
|
|
inputs_to_unscrubbed_outputs = {input_jar: ctx.actions.declare_output(
|
|
"proguard_output_jars/{}/{}_{}_obfuscated.jar".format(_UNSCRUBBED_JARS_DIR, input_jar.short_path, i),
|
|
) for i, input_jar in enumerate(input_jars.keys())}
|
|
mapping = ctx.actions.declare_output("proguard/mapping.txt")
|
|
configuration = ctx.actions.declare_output("proguard/configuration.txt")
|
|
seeds = ctx.actions.declare_output("proguard/seeds.txt")
|
|
usage = ctx.actions.declare_output("proguard/usage.txt")
|
|
|
|
command_line_args = _get_proguard_command_line_args(
|
|
ctx,
|
|
inputs_to_unscrubbed_outputs,
|
|
proguard_configs,
|
|
mapping,
|
|
configuration,
|
|
seeds,
|
|
usage,
|
|
ctx.attrs._android_toolchain[AndroidToolchainInfo],
|
|
)
|
|
|
|
command_line_args_file = ctx.actions.write("proguard/command-line.txt", command_line_args)
|
|
|
|
if ctx.attrs.skip_proguard:
|
|
return ProguardOutput(
|
|
jars_to_owners = input_jars,
|
|
proguard_configuration_output_file = None,
|
|
proguard_mapping_output_file = mapping,
|
|
proguard_artifacts = [command_line_args_file, mapping],
|
|
)
|
|
else:
|
|
unscrubbed_output_jars = {unscrubbed_output: input_jars[input_jar] for input_jar, unscrubbed_output in inputs_to_unscrubbed_outputs.items()}
|
|
run_proguard(
|
|
ctx,
|
|
ctx.attrs._android_toolchain[AndroidToolchainInfo],
|
|
ctx.attrs._java_toolchain[JavaToolchainInfo],
|
|
command_line_args_file,
|
|
command_line_args,
|
|
mapping,
|
|
)
|
|
output_jars = {}
|
|
for i, (unscrubbed_jar, target_label) in enumerate(unscrubbed_output_jars.items()):
|
|
output = ctx.actions.declare_output(unscrubbed_jar.short_path.replace("{}/".format(_UNSCRUBBED_JARS_DIR), ""))
|
|
ctx.actions.run(
|
|
cmd_args([ctx.attrs._java_toolchain[JavaToolchainInfo].zip_scrubber, unscrubbed_jar, output.as_output()]),
|
|
category = "scrub_jar",
|
|
identifier = str(i),
|
|
)
|
|
output_jars[output] = target_label
|
|
|
|
return ProguardOutput(
|
|
jars_to_owners = output_jars,
|
|
proguard_configuration_output_file = configuration,
|
|
proguard_mapping_output_file = mapping,
|
|
proguard_artifacts = [command_line_args_file, mapping, configuration, seeds, usage],
|
|
)
|