noredink-ui/prelude/android/aapt2_link.bzl

118 lines
4.9 KiB
Python
Raw Normal View History

# 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_providers.bzl", "Aapt2LinkInfo")
BASE_PACKAGE_ID = 0x7f
def get_aapt2_link(
ctx: "context",
android_toolchain: "AndroidToolchainInfo",
aapt2_compile_rules: ["artifact"],
android_manifest: "artifact",
includes_vector_drawables: bool.type,
no_auto_version: bool.type,
no_version_transitions: bool.type,
no_auto_add_overlay: bool.type,
use_proto_format: bool.type,
no_resource_removal: bool.type,
should_keep_raw_values: bool.type,
package_id_offset: int.type,
resource_stable_ids: ["artifact", None],
preferred_density: [str.type, None],
min_sdk: [str.type, None],
filter_locales: bool.type,
locales: [str.type],
compiled_resource_apks: ["artifact"],
additional_aapt2_params: [str.type],
extra_filtered_resources: [str.type]) -> Aapt2LinkInfo.type:
aapt2_command = cmd_args(android_toolchain.aapt2)
aapt2_command.add("link")
# aapt2 only supports @ for -R or input files, not for all args, so we pass in all "normal"
# args here.
resources_apk = ctx.actions.declare_output("resource-apk.ap_")
aapt2_command.add(["-o", resources_apk.as_output()])
proguard_config = ctx.actions.declare_output("proguard_config.pro")
aapt2_command.add(["--proguard", proguard_config.as_output()])
# We don't need the R.java output, but aapt2 won't output R.txt unless we also request R.java.
r_dot_java = ctx.actions.declare_output("initial-rdotjava", dir = True)
aapt2_command.add(["--java", r_dot_java.as_output()])
r_dot_txt = ctx.actions.declare_output("R.txt")
aapt2_command.add(["--output-text-symbols", r_dot_txt.as_output()])
aapt2_command.add(["--manifest", android_manifest])
aapt2_command.add(["-I", android_toolchain.android_jar])
if includes_vector_drawables:
aapt2_command.add("--no-version-vectors")
if no_auto_version:
aapt2_command.add("--no-auto-version")
if no_version_transitions:
aapt2_command.add("--no-version-transitions")
if not no_auto_add_overlay:
aapt2_command.add("--auto-add-overlay")
if use_proto_format:
aapt2_command.add("--proto-format")
if no_resource_removal:
aapt2_command.add("--no-resource-removal")
if should_keep_raw_values:
aapt2_command.add("--keep-raw-values")
if package_id_offset != 0:
aapt2_command.add(["--package-id", "0x{}".format(BASE_PACKAGE_ID + package_id_offset)])
if resource_stable_ids != None:
aapt2_command.add(["--stable-ids", resource_stable_ids])
if preferred_density != None:
aapt2_command.add(["--preferred-density", preferred_density])
if min_sdk != None:
aapt2_command.add(["--min-sdk-version", min_sdk])
if filter_locales and len(locales) > 0:
aapt2_command.add("-c")
# "NONE" means "en", update the list of locales
aapt2_command.add(cmd_args([locale if locale != "NONE" else "en" for locale in locales], delimiter = ","))
for compiled_resource_apk in compiled_resource_apks:
aapt2_command.add(["-I", compiled_resource_apk])
aapt2_compile_rules_args_file = ctx.actions.write("aapt2_compile_rules_args_file", cmd_args(aapt2_compile_rules, delimiter = " "))
aapt2_command.add("-R")
aapt2_command.add(cmd_args(aapt2_compile_rules_args_file, format = "@{}"))
aapt2_command.hidden(aapt2_compile_rules)
aapt2_command.add(additional_aapt2_params)
ctx.actions.run(aapt2_command, category = "aapt2_link")
# The normal resource filtering apparatus is super slow, because it extracts the whole apk,
# strips files out of it, then repackages it.
#
# This is a faster filtering step that just uses zip -d to remove entries from the archive.
# It's also superbly dangerous.
if len(extra_filtered_resources) > 0:
filtered_resources_apk = ctx.actions.declare_output("filtered-resource-apk.ap_")
filter_resources_sh_cmd = cmd_args([
"sh",
"-c",
'cp "$1" "$2" && chmod 644 "$2" && zip -d "$2" "$3"',
"--",
resources_apk,
filtered_resources_apk.as_output(),
extra_filtered_resources,
])
ctx.actions.run(filter_resources_sh_cmd, category = "aapt2_filter_resources")
primary_resources_apk = filtered_resources_apk
else:
primary_resources_apk = resources_apk
return Aapt2LinkInfo(
primary_resources_apk = primary_resources_apk,
proguard_config_file = proguard_config,
r_dot_txt = r_dot_txt,
)