1*9e965d6fSRomain Jobredeaux# Copyright 2018 The Bazel Authors. All rights reserved. 2*9e965d6fSRomain Jobredeaux# 3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License. 5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at 6*9e965d6fSRomain Jobredeaux# 7*9e965d6fSRomain Jobredeaux# http://www.apache.org/licenses/LICENSE-2.0 8*9e965d6fSRomain Jobredeaux# 9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software 10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS, 11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and 13*9e965d6fSRomain Jobredeaux# limitations under the License. 14*9e965d6fSRomain Jobredeaux"""Methods to process Android resources.""" 15*9e965d6fSRomain Jobredeaux 16*9e965d6fSRomain Jobredeauxload(":constants.bzl", "constants") 17*9e965d6fSRomain Jobredeauxload(":utils.bzl", "utils") 18*9e965d6fSRomain Jobredeaux 19*9e965d6fSRomain Jobredeaux# Android resource types, see https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/tools/aapt2/Resource.h 20*9e965d6fSRomain Jobredeauxres_types = [ 21*9e965d6fSRomain Jobredeaux "anim", 22*9e965d6fSRomain Jobredeaux "animator", 23*9e965d6fSRomain Jobredeaux "array", 24*9e965d6fSRomain Jobredeaux "attr", 25*9e965d6fSRomain Jobredeaux "^attr-private", 26*9e965d6fSRomain Jobredeaux "bool", 27*9e965d6fSRomain Jobredeaux "color", 28*9e965d6fSRomain Jobredeaux "configVarying", # Not really a type, but it shows up in some CTS tests 29*9e965d6fSRomain Jobredeaux "dimen", 30*9e965d6fSRomain Jobredeaux "drawable", 31*9e965d6fSRomain Jobredeaux "font", 32*9e965d6fSRomain Jobredeaux "fraction", 33*9e965d6fSRomain Jobredeaux "id", 34*9e965d6fSRomain Jobredeaux "integer", 35*9e965d6fSRomain Jobredeaux "interpolator", 36*9e965d6fSRomain Jobredeaux "layout", 37*9e965d6fSRomain Jobredeaux "macro", 38*9e965d6fSRomain Jobredeaux "menu", 39*9e965d6fSRomain Jobredeaux "mipmap", 40*9e965d6fSRomain Jobredeaux "navigation", 41*9e965d6fSRomain Jobredeaux "plurals", 42*9e965d6fSRomain Jobredeaux "raw", 43*9e965d6fSRomain Jobredeaux "string", 44*9e965d6fSRomain Jobredeaux "style", 45*9e965d6fSRomain Jobredeaux "styleable", 46*9e965d6fSRomain Jobredeaux "transition", 47*9e965d6fSRomain Jobredeaux "xml", 48*9e965d6fSRomain Jobredeaux] 49*9e965d6fSRomain Jobredeaux 50*9e965d6fSRomain Jobredeauxdef get_assets_dir(asset, base_dir): 51*9e965d6fSRomain Jobredeaux """Build the full assets directory sanitizing the input first.""" 52*9e965d6fSRomain Jobredeaux if base_dir == "": 53*9e965d6fSRomain Jobredeaux # some targets specify assets files and set assets_dirs = "" 54*9e965d6fSRomain Jobredeaux return asset.dirname 55*9e965d6fSRomain Jobredeaux asset_path = asset.path.rstrip("/") 56*9e965d6fSRomain Jobredeaux base_dir = base_dir.rstrip("/") 57*9e965d6fSRomain Jobredeaux if asset_path.endswith("/" + base_dir): 58*9e965d6fSRomain Jobredeaux return asset_path 59*9e965d6fSRomain Jobredeaux return "%s/%s" % (asset_path.rpartition("/%s/" % base_dir)[0], base_dir) 60*9e965d6fSRomain Jobredeaux 61*9e965d6fSRomain Jobredeauxdef compile_resources(ctx, lib_strategy = True): 62*9e965d6fSRomain Jobredeaux """Compiles android resources using aapt2 63*9e965d6fSRomain Jobredeaux 64*9e965d6fSRomain Jobredeaux Args: 65*9e965d6fSRomain Jobredeaux ctx: The context. 66*9e965d6fSRomain Jobredeaux lib_strategy: If to use library strategy or bucket. Default is lib strategy. 67*9e965d6fSRomain Jobredeaux 68*9e965d6fSRomain Jobredeaux Returns: 69*9e965d6fSRomain Jobredeaux A list of compiled android resource archives (.flata) files, otherwise None 70*9e965d6fSRomain Jobredeaux if data is None or empty. 71*9e965d6fSRomain Jobredeaux """ 72*9e965d6fSRomain Jobredeaux res_dir_file_map = partition_by_res_dirs(ctx.rule.files.resource_files) 73*9e965d6fSRomain Jobredeaux if lib_strategy: 74*9e965d6fSRomain Jobredeaux return _compile_library_resouces(ctx, res_dir_file_map) 75*9e965d6fSRomain Jobredeaux res_dir_buckets_map = _bucketize_resources(ctx, res_dir_file_map) 76*9e965d6fSRomain Jobredeaux return _compile_bucketized_resources(ctx, res_dir_buckets_map) 77*9e965d6fSRomain Jobredeaux 78*9e965d6fSRomain Jobredeauxdef partition_by_res_dirs(res_files): 79*9e965d6fSRomain Jobredeaux """Partitions the resources by res directories. 80*9e965d6fSRomain Jobredeaux 81*9e965d6fSRomain Jobredeaux Args: 82*9e965d6fSRomain Jobredeaux res_files: A list of resource artifacts files. 83*9e965d6fSRomain Jobredeaux 84*9e965d6fSRomain Jobredeaux Returns: 85*9e965d6fSRomain Jobredeaux A map of "res" directories to files corresponding to the directory. 86*9e965d6fSRomain Jobredeaux """ 87*9e965d6fSRomain Jobredeaux if not res_files: 88*9e965d6fSRomain Jobredeaux return None 89*9e965d6fSRomain Jobredeaux 90*9e965d6fSRomain Jobredeaux # Given the fact that res directories can be named anything and 91*9e965d6fSRomain Jobredeaux # its not possible to distinguish between directories and regular files 92*9e965d6fSRomain Jobredeaux # during analysis time, we use file extensions as an heuristic to group 93*9e965d6fSRomain Jobredeaux # resource files. All Android resource files have the following form 94*9e965d6fSRomain Jobredeaux # res-dir/type-dir/res_file. When we see a regular file (by looking at 95*9e965d6fSRomain Jobredeaux # the extesion) we use the directory two levels up as the grouping dir. 96*9e965d6fSRomain Jobredeaux # Most of the resource directories will contain at least one file with 97*9e965d6fSRomain Jobredeaux # and extension, so this heuristic will generally result in good groupings. 98*9e965d6fSRomain Jobredeaux res_non_values_file_map = {} 99*9e965d6fSRomain Jobredeaux res_value_file_map = {} 100*9e965d6fSRomain Jobredeaux res_dir_map = {} 101*9e965d6fSRomain Jobredeaux for res_file in res_files: 102*9e965d6fSRomain Jobredeaux if res_file.is_directory: 103*9e965d6fSRomain Jobredeaux res_dir_map.setdefault(res_file.path, []).append(res_file) 104*9e965d6fSRomain Jobredeaux else: 105*9e965d6fSRomain Jobredeaux path_segments = res_file.dirname.rsplit("/", 1) 106*9e965d6fSRomain Jobredeaux root_dir = path_segments[0] 107*9e965d6fSRomain Jobredeaux if path_segments[1].startswith("values"): 108*9e965d6fSRomain Jobredeaux res_value_file_map.setdefault(root_dir, []).append(res_file) 109*9e965d6fSRomain Jobredeaux else: 110*9e965d6fSRomain Jobredeaux res_non_values_file_map.setdefault(root_dir, []).append(res_file) 111*9e965d6fSRomain Jobredeaux return { 112*9e965d6fSRomain Jobredeaux "values": res_value_file_map, 113*9e965d6fSRomain Jobredeaux "non-values": res_non_values_file_map, 114*9e965d6fSRomain Jobredeaux "res_dir": res_dir_map, 115*9e965d6fSRomain Jobredeaux } 116*9e965d6fSRomain Jobredeaux 117*9e965d6fSRomain Jobredeauxdef _bucketize_resources(ctx, data): 118*9e965d6fSRomain Jobredeaux """Bucketizes resources by type. 119*9e965d6fSRomain Jobredeaux 120*9e965d6fSRomain Jobredeaux Args: 121*9e965d6fSRomain Jobredeaux ctx: The context. 122*9e965d6fSRomain Jobredeaux data: A map of "res" directories to files corresponding to the directory. 123*9e965d6fSRomain Jobredeaux 124*9e965d6fSRomain Jobredeaux Returns: 125*9e965d6fSRomain Jobredeaux A map of "res" directories to "res" buckets, None when there no resource 126*9e965d6fSRomain Jobredeaux files to compile. 127*9e965d6fSRomain Jobredeaux """ 128*9e965d6fSRomain Jobredeaux if not data: 129*9e965d6fSRomain Jobredeaux return None 130*9e965d6fSRomain Jobredeaux 131*9e965d6fSRomain Jobredeaux # Create backing files for the resource sharder. 132*9e965d6fSRomain Jobredeaux res_dir_buckets_map = {} 133*9e965d6fSRomain Jobredeaux for i, res_dir in enumerate(data.keys()): 134*9e965d6fSRomain Jobredeaux res_buckets = [] 135*9e965d6fSRomain Jobredeaux typed_outputs = [] 136*9e965d6fSRomain Jobredeaux 137*9e965d6fSRomain Jobredeaux for r_type in res_types: 138*9e965d6fSRomain Jobredeaux for idx in range(ctx.attr._mi_res_shards): 139*9e965d6fSRomain Jobredeaux res_bucket = utils.isolated_declare_file( 140*9e965d6fSRomain Jobredeaux ctx, 141*9e965d6fSRomain Jobredeaux ctx.label.name + "_mi/resources/buckets/%d/%s_%s.zip" % (i, r_type, idx), 142*9e965d6fSRomain Jobredeaux ) 143*9e965d6fSRomain Jobredeaux res_buckets.append(res_bucket) 144*9e965d6fSRomain Jobredeaux typed_outputs.append(r_type + ":" + res_bucket.path) 145*9e965d6fSRomain Jobredeaux 146*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 147*9e965d6fSRomain Jobredeaux args.use_param_file(param_file_arg = "-flagfile=%s") 148*9e965d6fSRomain Jobredeaux args.set_param_file_format("multiline") 149*9e965d6fSRomain Jobredeaux args.add_joined("-typed_outputs", typed_outputs, join_with = ",") 150*9e965d6fSRomain Jobredeaux if data[res_dir]: 151*9e965d6fSRomain Jobredeaux args.add_joined("-res_paths", data[res_dir], join_with = ",") 152*9e965d6fSRomain Jobredeaux 153*9e965d6fSRomain Jobredeaux ctx.actions.run( 154*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 155*9e965d6fSRomain Jobredeaux arguments = ["bucketize", args], 156*9e965d6fSRomain Jobredeaux inputs = data[res_dir], 157*9e965d6fSRomain Jobredeaux outputs = res_buckets, 158*9e965d6fSRomain Jobredeaux mnemonic = "BucketizeRes", 159*9e965d6fSRomain Jobredeaux progress_message = "MI Bucketize resources for %s" % res_dir, 160*9e965d6fSRomain Jobredeaux ) 161*9e965d6fSRomain Jobredeaux res_dir_buckets_map[res_dir] = res_buckets 162*9e965d6fSRomain Jobredeaux return res_dir_buckets_map 163*9e965d6fSRomain Jobredeaux 164*9e965d6fSRomain Jobredeauxdef _compile_bucketized_resources(ctx, data): 165*9e965d6fSRomain Jobredeaux """Compiles android resources using aapt2 166*9e965d6fSRomain Jobredeaux 167*9e965d6fSRomain Jobredeaux Args: 168*9e965d6fSRomain Jobredeaux ctx: The context. 169*9e965d6fSRomain Jobredeaux data: A map of res directories to resource buckets. 170*9e965d6fSRomain Jobredeaux 171*9e965d6fSRomain Jobredeaux Returns: 172*9e965d6fSRomain Jobredeaux A list of compiled android resource archives (.flata) files, otherwise None 173*9e965d6fSRomain Jobredeaux if data is None or empty. 174*9e965d6fSRomain Jobredeaux """ 175*9e965d6fSRomain Jobredeaux if not data: 176*9e965d6fSRomain Jobredeaux return constants.EMPTY_LIST 177*9e965d6fSRomain Jobredeaux 178*9e965d6fSRomain Jobredeaux # TODO(mauriciogg): use no-crunch. We are using crunch to process 9-patch 179*9e965d6fSRomain Jobredeaux # pngs should be disabled in general either by having a more granular flag 180*9e965d6fSRomain Jobredeaux # in aapt2 or bucketizing 9patch pngs. See (b/70578281) 181*9e965d6fSRomain Jobredeaux compiled_res_buckets = [] 182*9e965d6fSRomain Jobredeaux for res_dir, res_buckets in data.items(): 183*9e965d6fSRomain Jobredeaux for res_bucket in res_buckets: 184*9e965d6fSRomain Jobredeaux # Note that extension matters for aapt2. 185*9e965d6fSRomain Jobredeaux out = utils.isolated_declare_file( 186*9e965d6fSRomain Jobredeaux ctx, 187*9e965d6fSRomain Jobredeaux res_bucket.basename + ".flata", 188*9e965d6fSRomain Jobredeaux sibling = res_bucket, 189*9e965d6fSRomain Jobredeaux ) 190*9e965d6fSRomain Jobredeaux ctx.actions.run( 191*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 192*9e965d6fSRomain Jobredeaux arguments = [ 193*9e965d6fSRomain Jobredeaux "compile", 194*9e965d6fSRomain Jobredeaux "--aapt2=" + utils.first(ctx.attr._aapt2.files).path, 195*9e965d6fSRomain Jobredeaux "--in=" + res_bucket.path, 196*9e965d6fSRomain Jobredeaux "--out=" + out.path, 197*9e965d6fSRomain Jobredeaux ], 198*9e965d6fSRomain Jobredeaux inputs = [res_bucket] + ctx.attr._aapt2.files.to_list(), 199*9e965d6fSRomain Jobredeaux outputs = [out], 200*9e965d6fSRomain Jobredeaux mnemonic = "CompileRes", 201*9e965d6fSRomain Jobredeaux progress_message = "MI Compiling resources for %s" % res_dir, 202*9e965d6fSRomain Jobredeaux ) 203*9e965d6fSRomain Jobredeaux compiled_res_buckets.append(out) 204*9e965d6fSRomain Jobredeaux 205*9e965d6fSRomain Jobredeaux return compiled_res_buckets 206*9e965d6fSRomain Jobredeaux 207*9e965d6fSRomain Jobredeauxdef _compile_library_resouces(ctx, data): 208*9e965d6fSRomain Jobredeaux """Compiles android resources using aapt2 209*9e965d6fSRomain Jobredeaux 210*9e965d6fSRomain Jobredeaux Args: 211*9e965d6fSRomain Jobredeaux ctx: The context. 212*9e965d6fSRomain Jobredeaux data: A map of res directories to resource buckets. 213*9e965d6fSRomain Jobredeaux 214*9e965d6fSRomain Jobredeaux Returns: 215*9e965d6fSRomain Jobredeaux A list of compiled android resource archives (.flata) files, otherwise None 216*9e965d6fSRomain Jobredeaux if data is None or empty. 217*9e965d6fSRomain Jobredeaux """ 218*9e965d6fSRomain Jobredeaux if not data: 219*9e965d6fSRomain Jobredeaux return constants.EMPTY_LIST 220*9e965d6fSRomain Jobredeaux 221*9e965d6fSRomain Jobredeaux # TODO(mauriciogg): use no-crunch. We are using crunch to process 9-patch 222*9e965d6fSRomain Jobredeaux # pngs should be disabled in general either by having a more granular flag 223*9e965d6fSRomain Jobredeaux # in aapt2 or bucketizing 9patch pngs. See (b/70578281) 224*9e965d6fSRomain Jobredeaux compiled_res_dirs = [] 225*9e965d6fSRomain Jobredeaux for res_type in data.keys(): 226*9e965d6fSRomain Jobredeaux for res_dir in data[res_type].keys(): 227*9e965d6fSRomain Jobredeaux # Note that extension matters for aapt2. 228*9e965d6fSRomain Jobredeaux out = utils.isolated_declare_file( 229*9e965d6fSRomain Jobredeaux ctx, 230*9e965d6fSRomain Jobredeaux ctx.label.name + "_mi/resources/%s_%s.flata" % (res_dir.replace("/", "_"), res_type), 231*9e965d6fSRomain Jobredeaux ) 232*9e965d6fSRomain Jobredeaux compiled_res_dirs.append(out) 233*9e965d6fSRomain Jobredeaux 234*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 235*9e965d6fSRomain Jobredeaux args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True) 236*9e965d6fSRomain Jobredeaux args.set_param_file_format("multiline") 237*9e965d6fSRomain Jobredeaux args.add("-aapt2", ctx.file._aapt2) 238*9e965d6fSRomain Jobredeaux args.add("-in", res_dir) 239*9e965d6fSRomain Jobredeaux args.add("-out", out) 240*9e965d6fSRomain Jobredeaux ctx.actions.run( 241*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 242*9e965d6fSRomain Jobredeaux arguments = ["compile", args], 243*9e965d6fSRomain Jobredeaux inputs = data[res_type][res_dir] + ctx.attr._aapt2.files.to_list(), 244*9e965d6fSRomain Jobredeaux outputs = [out], 245*9e965d6fSRomain Jobredeaux mnemonic = "CompileRes", 246*9e965d6fSRomain Jobredeaux progress_message = "MI Compiling resources for %s" % res_dir, 247*9e965d6fSRomain Jobredeaux ) 248*9e965d6fSRomain Jobredeaux return compiled_res_dirs 249*9e965d6fSRomain Jobredeaux 250*9e965d6fSRomain Jobredeauxdef link_resources( 251*9e965d6fSRomain Jobredeaux ctx, 252*9e965d6fSRomain Jobredeaux manifest, 253*9e965d6fSRomain Jobredeaux java_package, 254*9e965d6fSRomain Jobredeaux android_jar, 255*9e965d6fSRomain Jobredeaux resource_archives, 256*9e965d6fSRomain Jobredeaux assets, 257*9e965d6fSRomain Jobredeaux assets_dirs): 258*9e965d6fSRomain Jobredeaux """Links android resources using aapt2 259*9e965d6fSRomain Jobredeaux 260*9e965d6fSRomain Jobredeaux Args: 261*9e965d6fSRomain Jobredeaux ctx: The context. 262*9e965d6fSRomain Jobredeaux manifest: The AndroidManifest.xml file 263*9e965d6fSRomain Jobredeaux java_package: The package to use to generate R.java 264*9e965d6fSRomain Jobredeaux android_jar: The android jar 265*9e965d6fSRomain Jobredeaux resource_archives: List of intermediate compiled android resource files. 266*9e965d6fSRomain Jobredeaux assets: The list of assets. 267*9e965d6fSRomain Jobredeaux assets_dirs: The list of directories for the assets. 268*9e965d6fSRomain Jobredeaux 269*9e965d6fSRomain Jobredeaux Returns: 270*9e965d6fSRomain Jobredeaux The resource apk and the R java file generated by aapt2. 271*9e965d6fSRomain Jobredeaux """ 272*9e965d6fSRomain Jobredeaux if not resource_archives: 273*9e965d6fSRomain Jobredeaux return None 274*9e965d6fSRomain Jobredeaux 275*9e965d6fSRomain Jobredeaux resource_apk = utils.isolated_declare_file(ctx, ctx.label.name + "_mi/resources/resource.apk") 276*9e965d6fSRomain Jobredeaux rjava_zip = utils.isolated_declare_file(ctx, "R.zip", sibling = resource_apk) 277*9e965d6fSRomain Jobredeaux 278*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 279*9e965d6fSRomain Jobredeaux args.use_param_file(param_file_arg = "-flagfile=%s", use_always = True) 280*9e965d6fSRomain Jobredeaux args.add("-aapt2", ctx.executable._aapt2) 281*9e965d6fSRomain Jobredeaux args.add("-sdk_jar", android_jar) 282*9e965d6fSRomain Jobredeaux args.add("-manifest", manifest) 283*9e965d6fSRomain Jobredeaux args.add("-pkg", java_package) 284*9e965d6fSRomain Jobredeaux args.add("-src_jar", rjava_zip) 285*9e965d6fSRomain Jobredeaux args.add("-out", resource_apk) 286*9e965d6fSRomain Jobredeaux args.add_joined("-res_dirs", resource_archives, join_with = ",") 287*9e965d6fSRomain Jobredeaux args.add_joined("-asset_dirs", assets_dirs, join_with = ",") 288*9e965d6fSRomain Jobredeaux 289*9e965d6fSRomain Jobredeaux ctx.actions.run( 290*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 291*9e965d6fSRomain Jobredeaux arguments = ["link", args], 292*9e965d6fSRomain Jobredeaux inputs = depset( 293*9e965d6fSRomain Jobredeaux [manifest, android_jar, ctx.executable._aapt2] + resource_archives, 294*9e965d6fSRomain Jobredeaux transitive = [assets], 295*9e965d6fSRomain Jobredeaux ), 296*9e965d6fSRomain Jobredeaux outputs = [resource_apk, rjava_zip], 297*9e965d6fSRomain Jobredeaux mnemonic = "LinkRes", 298*9e965d6fSRomain Jobredeaux progress_message = "MI Linking resources for %s" % ctx.label, 299*9e965d6fSRomain Jobredeaux ) 300*9e965d6fSRomain Jobredeaux return resource_apk, rjava_zip 301*9e965d6fSRomain Jobredeaux 302*9e965d6fSRomain Jobredeauxdef liteparse(ctx): 303*9e965d6fSRomain Jobredeaux """Creates an R.pb which contains the resource ids gotten from a light parse. 304*9e965d6fSRomain Jobredeaux 305*9e965d6fSRomain Jobredeaux Args: 306*9e965d6fSRomain Jobredeaux ctx: The context. 307*9e965d6fSRomain Jobredeaux 308*9e965d6fSRomain Jobredeaux Returns: 309*9e965d6fSRomain Jobredeaux The resource pb file object. 310*9e965d6fSRomain Jobredeaux """ 311*9e965d6fSRomain Jobredeaux if not hasattr(ctx.rule.files, "resource_files"): 312*9e965d6fSRomain Jobredeaux return None 313*9e965d6fSRomain Jobredeaux 314*9e965d6fSRomain Jobredeaux r_pb = utils.isolated_declare_file(ctx, ctx.label.name + "_mi/resources/R.pb") 315*9e965d6fSRomain Jobredeaux 316*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 317*9e965d6fSRomain Jobredeaux args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True) 318*9e965d6fSRomain Jobredeaux args.set_param_file_format("multiline") 319*9e965d6fSRomain Jobredeaux args.add_joined("--res_files", ctx.rule.files.resource_files, join_with = ",") 320*9e965d6fSRomain Jobredeaux args.add("--out", r_pb) 321*9e965d6fSRomain Jobredeaux 322*9e965d6fSRomain Jobredeaux ctx.actions.run( 323*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 324*9e965d6fSRomain Jobredeaux arguments = ["liteparse", args], 325*9e965d6fSRomain Jobredeaux inputs = ctx.rule.files.resource_files, 326*9e965d6fSRomain Jobredeaux outputs = [r_pb], 327*9e965d6fSRomain Jobredeaux mnemonic = "ResLiteParse", 328*9e965d6fSRomain Jobredeaux progress_message = "MI Lite parse Android Resources %s" % ctx.label, 329*9e965d6fSRomain Jobredeaux ) 330*9e965d6fSRomain Jobredeaux return r_pb 331*9e965d6fSRomain Jobredeaux 332*9e965d6fSRomain Jobredeauxdef compiletime_r_srcjar(ctx, output_srcjar, r_pbs, package): 333*9e965d6fSRomain Jobredeaux """Create R.srcjar from the given R.pb files in the transitive closure. 334*9e965d6fSRomain Jobredeaux 335*9e965d6fSRomain Jobredeaux Args: 336*9e965d6fSRomain Jobredeaux ctx: The context. 337*9e965d6fSRomain Jobredeaux output_srcjar: The output R source jar artifact. 338*9e965d6fSRomain Jobredeaux r_pbs: Transitive set of resource pbs. 339*9e965d6fSRomain Jobredeaux package: The package name of the compile-time R.java. 340*9e965d6fSRomain Jobredeaux """ 341*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 342*9e965d6fSRomain Jobredeaux args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True) 343*9e965d6fSRomain Jobredeaux args.set_param_file_format("multiline") 344*9e965d6fSRomain Jobredeaux args.add("-rJavaOutput", output_srcjar) 345*9e965d6fSRomain Jobredeaux args.add("-packageForR", package) 346*9e965d6fSRomain Jobredeaux args.add_joined("-resourcePbs", r_pbs, join_with = ",") 347*9e965d6fSRomain Jobredeaux 348*9e965d6fSRomain Jobredeaux ctx.actions.run( 349*9e965d6fSRomain Jobredeaux executable = ctx.executable._android_kit, 350*9e965d6fSRomain Jobredeaux arguments = ["rstub", args], 351*9e965d6fSRomain Jobredeaux inputs = r_pbs, 352*9e965d6fSRomain Jobredeaux outputs = [output_srcjar], 353*9e965d6fSRomain Jobredeaux mnemonic = "CompileTimeRSrcjar", 354*9e965d6fSRomain Jobredeaux progress_message = "MI Make compile-time R.srcjar %s" % ctx.label, 355*9e965d6fSRomain Jobredeaux ) 356