xref: /aosp_15_r20/external/bazelbuild-rules_android/mobile_install/transform.bzl (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
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"""Transform contains data transformation methods."""
15*9e965d6fSRomain Jobredeaux
16*9e965d6fSRomain Jobredeauxload(":constants.bzl", "constants")
17*9e965d6fSRomain Jobredeauxload(":utils.bzl", "utils")
18*9e965d6fSRomain Jobredeauxload("//rules/flags:flags.bzl", _flags = "flags")
19*9e965d6fSRomain Jobredeaux
20*9e965d6fSRomain Jobredeauxdef _declare_file(ctx, filename, sibling = None):
21*9e965d6fSRomain Jobredeaux    return utils.isolated_declare_file(ctx, filename, sibling = sibling)
22*9e965d6fSRomain Jobredeaux
23*9e965d6fSRomain Jobredeauxdef filter_jars(name, data):
24*9e965d6fSRomain Jobredeaux    """Filters out files that are not compiled Jars - includes header Jars.
25*9e965d6fSRomain Jobredeaux
26*9e965d6fSRomain Jobredeaux    Args:
27*9e965d6fSRomain Jobredeaux      name: Name of the file to filter, check uses endswith on the path.
28*9e965d6fSRomain Jobredeaux      data: The list of tuples where each entry contains the originating file path
29*9e965d6fSRomain Jobredeaux        and file to apply the filter.
30*9e965d6fSRomain Jobredeaux
31*9e965d6fSRomain Jobredeaux    Returns:
32*9e965d6fSRomain Jobredeaux      A list of tuples where each entry contains the originating Jar path and the
33*9e965d6fSRomain Jobredeaux      Jar file.
34*9e965d6fSRomain Jobredeaux    """
35*9e965d6fSRomain Jobredeaux    return [jar for jar in data if not jar.path.endswith(name)]
36*9e965d6fSRomain Jobredeaux
37*9e965d6fSRomain Jobredeauxdef dex(
38*9e965d6fSRomain Jobredeaux        ctx,
39*9e965d6fSRomain Jobredeaux        data,
40*9e965d6fSRomain Jobredeaux        deps = constants.EMPTY_LIST,
41*9e965d6fSRomain Jobredeaux        num_shards = None,
42*9e965d6fSRomain Jobredeaux        create_file = _declare_file,
43*9e965d6fSRomain Jobredeaux        desugar = True):
44*9e965d6fSRomain Jobredeaux    """Dex a list of Jars.
45*9e965d6fSRomain Jobredeaux
46*9e965d6fSRomain Jobredeaux    Args:
47*9e965d6fSRomain Jobredeaux      ctx: The context.
48*9e965d6fSRomain Jobredeaux      data: The list of tuples where each entry contains the originating Jar
49*9e965d6fSRomain Jobredeaux        path and the Jar to Dex.
50*9e965d6fSRomain Jobredeaux      deps: The list of dependencies for the Jar being desugared.
51*9e965d6fSRomain Jobredeaux      num_shards: The number of shards to distribute the dexed files across,
52*9e965d6fSRomain Jobredeaux        this value overrides the default provided by ctx.attr._mi_dex_shards.
53*9e965d6fSRomain Jobredeaux      create_file: In rare occasions a custom method is required to
54*9e965d6fSRomain Jobredeaux        create a unique file, override the default here. The method must
55*9e965d6fSRomain Jobredeaux        implement the following interface:
56*9e965d6fSRomain Jobredeaux
57*9e965d6fSRomain Jobredeaux        def create_file(ctx, filename, sibling = None)
58*9e965d6fSRomain Jobredeaux        Args:
59*9e965d6fSRomain Jobredeaux          ctx: The context.
60*9e965d6fSRomain Jobredeaux          filename: string. The name of the file.
61*9e965d6fSRomain Jobredeaux          sibling: File. The location of the new file.
62*9e965d6fSRomain Jobredeaux
63*9e965d6fSRomain Jobredeaux        Returns:
64*9e965d6fSRomain Jobredeaux          A File.
65*9e965d6fSRomain Jobredeaux      desugar: A boolean that determines whether to apply desugaring.
66*9e965d6fSRomain Jobredeaux
67*9e965d6fSRomain Jobredeaux    Returns:
68*9e965d6fSRomain Jobredeaux      A list of tuples where each entry contains the originating Jar path and
69*9e965d6fSRomain Jobredeaux      the Dex shards.
70*9e965d6fSRomain Jobredeaux    """
71*9e965d6fSRomain Jobredeaux    if num_shards:
72*9e965d6fSRomain Jobredeaux        num_dex_shards = num_shards
73*9e965d6fSRomain Jobredeaux    elif _flags.get(ctx).use_custom_dex_shards:
74*9e965d6fSRomain Jobredeaux        num_dex_shards = _flags.get(ctx).num_dex_shards
75*9e965d6fSRomain Jobredeaux    else:
76*9e965d6fSRomain Jobredeaux        num_dex_shards = ctx.attr._mi_dex_shards
77*9e965d6fSRomain Jobredeaux
78*9e965d6fSRomain Jobredeaux    dex_files = []
79*9e965d6fSRomain Jobredeaux    for jar in data:
80*9e965d6fSRomain Jobredeaux        out_dex_shards = []
81*9e965d6fSRomain Jobredeaux        dirname = jar.basename + "_dex"
82*9e965d6fSRomain Jobredeaux        for i in range(num_shards or num_dex_shards):
83*9e965d6fSRomain Jobredeaux            out_dex_shards.append(create_file(
84*9e965d6fSRomain Jobredeaux                ctx,
85*9e965d6fSRomain Jobredeaux                dirname + "/" + str(i) + ".zip",
86*9e965d6fSRomain Jobredeaux                sibling = jar,
87*9e965d6fSRomain Jobredeaux            ))
88*9e965d6fSRomain Jobredeaux        utils.dex(ctx, jar, out_dex_shards, deps, desugar)
89*9e965d6fSRomain Jobredeaux        dex_files.append(out_dex_shards)
90*9e965d6fSRomain Jobredeaux    return dex_files
91*9e965d6fSRomain Jobredeaux
92*9e965d6fSRomain Jobredeauxdef extract_jar_resources(ctx, data, create_file = _declare_file):
93*9e965d6fSRomain Jobredeaux    """Extracts the non-class files from the list of Jars.
94*9e965d6fSRomain Jobredeaux
95*9e965d6fSRomain Jobredeaux    Args:
96*9e965d6fSRomain Jobredeaux      ctx: The context
97*9e965d6fSRomain Jobredeaux      data: The list of tuples where each entry contains the originating Jar
98*9e965d6fSRomain Jobredeaux        path and the Jar with resources to extract.
99*9e965d6fSRomain Jobredeaux      create_file: In rare occasions a custom method is required to
100*9e965d6fSRomain Jobredeaux        create a unique file, override the default here. The method must
101*9e965d6fSRomain Jobredeaux        implement the following interface:
102*9e965d6fSRomain Jobredeaux
103*9e965d6fSRomain Jobredeaux        def create_file(ctx, filename, sibling = None)
104*9e965d6fSRomain Jobredeaux        Args:
105*9e965d6fSRomain Jobredeaux          ctx: The context.
106*9e965d6fSRomain Jobredeaux          filename: string. The name of the file.
107*9e965d6fSRomain Jobredeaux          sibling: File. The location of the new file.
108*9e965d6fSRomain Jobredeaux
109*9e965d6fSRomain Jobredeaux        Returns:
110*9e965d6fSRomain Jobredeaux          A File.
111*9e965d6fSRomain Jobredeaux
112*9e965d6fSRomain Jobredeaux    Returns:
113*9e965d6fSRomain Jobredeaux      A list of extracted resource zips.
114*9e965d6fSRomain Jobredeaux    """
115*9e965d6fSRomain Jobredeaux    resources_files = []
116*9e965d6fSRomain Jobredeaux    for jar in data:
117*9e965d6fSRomain Jobredeaux        out_resources_file = create_file(
118*9e965d6fSRomain Jobredeaux            ctx,
119*9e965d6fSRomain Jobredeaux            jar.basename + "_resources.zip",
120*9e965d6fSRomain Jobredeaux            sibling = jar,
121*9e965d6fSRomain Jobredeaux        )
122*9e965d6fSRomain Jobredeaux        utils.extract_jar_resources(ctx, jar, out_resources_file)
123*9e965d6fSRomain Jobredeaux        resources_files.append(out_resources_file)
124*9e965d6fSRomain Jobredeaux    return resources_files
125*9e965d6fSRomain Jobredeaux
126*9e965d6fSRomain Jobredeauxdef merge_dex_shards(ctx, data, sibling):
127*9e965d6fSRomain Jobredeaux    """Merges all dex files in the transitive deps to a dex per shard.
128*9e965d6fSRomain Jobredeaux
129*9e965d6fSRomain Jobredeaux    Given a list of dex files (and resources.zips) this will create an
130*9e965d6fSRomain Jobredeaux    action per shard that runs dex_shard_merger on all dex files within that
131*9e965d6fSRomain Jobredeaux    shard.
132*9e965d6fSRomain Jobredeaux
133*9e965d6fSRomain Jobredeaux    Arguments:
134*9e965d6fSRomain Jobredeaux      ctx: The context.
135*9e965d6fSRomain Jobredeaux      data: A list of lists, where the inner list contains dex shards.
136*9e965d6fSRomain Jobredeaux      sibling: A file used to root the merged_dex shards.
137*9e965d6fSRomain Jobredeaux
138*9e965d6fSRomain Jobredeaux    Returns:
139*9e965d6fSRomain Jobredeaux      A list of merged dex shards.
140*9e965d6fSRomain Jobredeaux    """
141*9e965d6fSRomain Jobredeaux    merged_dex_shards = []
142*9e965d6fSRomain Jobredeaux    for idx, shard in enumerate(data):
143*9e965d6fSRomain Jobredeaux        #  To ensure resource is added at the beginning, R.zip is named as 00.zip
144*9e965d6fSRomain Jobredeaux        #  Thus data shards starts from 1 instead of 0 and ranges through 16
145*9e965d6fSRomain Jobredeaux        idx += 1
146*9e965d6fSRomain Jobredeaux
147*9e965d6fSRomain Jobredeaux        # Shards are sorted before deployment, to ensure all shards are correctly
148*9e965d6fSRomain Jobredeaux        # ordered 0 is padded to single digit shard counts
149*9e965d6fSRomain Jobredeaux        shard_name = "%s%s" % ("00"[len(str(idx)):], idx)
150*9e965d6fSRomain Jobredeaux        merged_dex_shard = utils.isolated_declare_file(
151*9e965d6fSRomain Jobredeaux            ctx,
152*9e965d6fSRomain Jobredeaux            "dex_shards/" + shard_name + ".zip",
153*9e965d6fSRomain Jobredeaux            sibling = sibling,
154*9e965d6fSRomain Jobredeaux        )
155*9e965d6fSRomain Jobredeaux        utils.merge_dex_shards(ctx, shard, merged_dex_shard)
156*9e965d6fSRomain Jobredeaux        merged_dex_shards.append(merged_dex_shard)
157*9e965d6fSRomain Jobredeaux    return merged_dex_shards
158