diff options
Diffstat (limited to 'rules/aapt.bzl')
-rw-r--r-- | rules/aapt.bzl | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/rules/aapt.bzl b/rules/aapt.bzl new file mode 100644 index 0000000..284d89a --- /dev/null +++ b/rules/aapt.bzl @@ -0,0 +1,200 @@ +# Copyright 2019 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. + +"""Bazel AAPT Commands.""" + +def _link( + ctx, + out_r_java, + out_resource_apk, + manifest = None, + java_package = None, + assets = depset([]), + assets_dirs = [], + compiled_resources = depset([]), + config_filters = [], + make_r_java_ids_non_final = False, + compatible_with_resource_shrinking = True, + enable_debug = False, + enable_static_lib = False, + android_jar = None, + aapt = None): + """Links compiled Android Resources with AAPT. + + Args: + ctx: The context. + out_r_java: A File. The R.java outputted by linking resources. + out_resource_apk: A File. The Resource APK outputted by linking resources. + manifest: A File. The AndroidManifest.xml. + java_package: A string. The Java package for the generated R.java. + assets: A list of Files. The list of assets from the transitive closure of + the project. + assets_dirs: A list of strings. The list of asset directories in the + transitive closure of the project. + compiled_resources: List of intermediate compiled android resource files. + config_filters: A list of Strings. The configuration filters. + make_r_java_ids_non_final: A bool. Makes the R.java produced from linkin + have non-final values. + compatible_with_resource_shrinking: A bool. When enabled produces the + output in proto format which is a requirement for resource shrinking. + enable_debug: A bool. Enable debugging + enable_static_lib: A bool. Enable static lib. + android_jar: A File. The Android Jar. + aapt: A FilesToRunProvider. The AAPT executable. + """ + + # Output the list of resources in reverse topological order. + resources_param = ctx.actions.declare_file( + out_r_java.basename + ".params", + sibling = out_r_java, + ) + args = ctx.actions.args() + args.use_param_file("%s", use_always = True) + args.set_param_file_format("multiline") + args.add_all(compiled_resources, expand_directories = True) + ctx.actions.run_shell( + command = """ +# Reverses the set of inputs that have been topologically ordered to utilize the +# overlay/override semantics of aapt2. +set -e + +echo $(tac $1) > $2 +""", + arguments = [args, resources_param.path], + outputs = [resources_param], + inputs = compiled_resources, + ) + + args = ctx.actions.args() + args.add("link") + if enable_static_lib: + args.add("--static-lib") + args.add("--no-version-vectors") + args.add("--no-static-lib-packages") # Turn off namespaced resource + + args.add("--manifest", manifest) + args.add("--auto-add-overlay") # Enables resource redefinition and merging + args.add("--override-styles-instead-of-overlaying") # mimic AAPT1. + if make_r_java_ids_non_final: + args.add("--non-final-ids") + if compatible_with_resource_shrinking: + args.add("--proto-format") + if enable_debug: + args.add("--debug-mode") + args.add("--custom-package", java_package) + args.add("-I", android_jar) + args.add_all(assets_dirs, before_each = "-A") + args.add("-R", resources_param, format = "@%s") + args.add("-0", ".apk") + args.add_joined("-c", config_filters, join_with = ",", omit_if_empty = True) + args.add("--java", out_r_java.path.rpartition(java_package.replace(".", "/"))[0]) + args.add("-o", out_resource_apk) + + ctx.actions.run( + executable = aapt, + arguments = [args], + inputs = depset( + [android_jar, resources_param] + + ([manifest] if manifest else []), + transitive = [assets, compiled_resources], + ), + outputs = [out_resource_apk, out_r_java], + mnemonic = "LinkAndroidResources", + progress_message = "ResV3 Linking Android Resources to %s" % out_resource_apk.short_path, + ) + +def _compile( + ctx, + out_dir, + resource_files, + aapt): + """Compile and store resources in a single archive. + + Args: + ctx: The context. + out_dir: File. A file to store the output. + resource_files: A list of Files. The list of resource files or directories + to process. + aapt: AAPT. Tool for compiling resources. + """ + if not out_dir: + fail("No output directory specified.") + if not out_dir.is_directory: + fail("Output directory is not a directory artifact.") + if not resource_files: + fail("No resource files given.") + + # Retrieves the list of files at runtime when a directory is passed. + args = ctx.actions.args() + args.add_all(resource_files, expand_directories = True) + + ctx.actions.run_shell( + command = """ +set -e + +AAPT=%s +OUT_DIR=%s +RESOURCE_FILES=$@ + +i=0 +declare -A out_dir_map +for f in ${RESOURCE_FILES}; do + res_dir="$(dirname $(dirname ${f}))" + if [ -z "${out_dir_map[${res_dir}]}" ]; then + out_dir="${OUT_DIR}/$((++i))" + mkdir -p ${out_dir} + out_dir_map[${res_dir}]="${out_dir}" + fi + # Outputs from multiple directories can overwrite the outputs. As we do not + # control the outputs for now store each in its own sub directory which will be + # captured by the over_dir. + # TODO(b/139757260): Re-evaluate this one compile per file or multiple and zip + # merge. + "${AAPT}" compile --legacy "${f}" -o "${out_dir_map[${res_dir}]}" +done +""" % (aapt.executable.path, out_dir.path), + tools = [aapt], + arguments = [args], + inputs = resource_files, + outputs = [out_dir], + mnemonic = "CompileAndroidResources", + progress_message = "ResV3 Compiling Android Resources in %s" % out_dir, + ) + +def _convert( + ctx, + out = None, + input = None, + to_proto = False, + aapt = None): + args = ctx.actions.args() + args.add("convert") + args.add("--output-format", ("proto" if to_proto else "binary")) + args.add("-o", out) + args.add(input) + + ctx.actions.run( + executable = aapt, + arguments = [args], + inputs = [input], + outputs = [out], + mnemonic = "AaptConvert", + progress_message = "ResV3 Convert to %s" % out.short_path, + ) + +aapt = struct( + link = _link, + compile = _compile, + convert = _convert, +) |