xref: /aosp_15_r20/external/angle/build/android/gyp/dist_aar.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker#
3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2017 The Chromium Authors
4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker"""Creates an Android .aar file."""
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Workerimport argparse
10*8975f5c5SAndroid Build Coastguard Workerimport os
11*8975f5c5SAndroid Build Coastguard Workerimport posixpath
12*8975f5c5SAndroid Build Coastguard Workerimport shutil
13*8975f5c5SAndroid Build Coastguard Workerimport sys
14*8975f5c5SAndroid Build Coastguard Workerimport tempfile
15*8975f5c5SAndroid Build Coastguard Workerimport zipfile
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Workerimport filter_zip
18*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils
19*8975f5c5SAndroid Build Coastguard Workerimport action_helpers  # build_utils adds //build to sys.path.
20*8975f5c5SAndroid Build Coastguard Workerimport zip_helpers
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard Worker
23*8975f5c5SAndroid Build Coastguard Worker_ANDROID_BUILD_DIR = os.path.dirname(os.path.dirname(__file__))
24*8975f5c5SAndroid Build Coastguard Worker
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Workerdef _MergeRTxt(r_paths, include_globs):
27*8975f5c5SAndroid Build Coastguard Worker  """Merging the given R.txt files and returns them as a string."""
28*8975f5c5SAndroid Build Coastguard Worker  all_lines = set()
29*8975f5c5SAndroid Build Coastguard Worker  for r_path in r_paths:
30*8975f5c5SAndroid Build Coastguard Worker    if include_globs and not build_utils.MatchesGlob(r_path, include_globs):
31*8975f5c5SAndroid Build Coastguard Worker      continue
32*8975f5c5SAndroid Build Coastguard Worker    with open(r_path) as f:
33*8975f5c5SAndroid Build Coastguard Worker      all_lines.update(f.readlines())
34*8975f5c5SAndroid Build Coastguard Worker  return ''.join(sorted(all_lines))
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Workerdef _MergeProguardConfigs(proguard_configs):
38*8975f5c5SAndroid Build Coastguard Worker  """Merging the given proguard config files and returns them as a string."""
39*8975f5c5SAndroid Build Coastguard Worker  ret = []
40*8975f5c5SAndroid Build Coastguard Worker  for config in proguard_configs:
41*8975f5c5SAndroid Build Coastguard Worker    ret.append('# FROM: {}'.format(config))
42*8975f5c5SAndroid Build Coastguard Worker    with open(config) as f:
43*8975f5c5SAndroid Build Coastguard Worker      ret.append(f.read())
44*8975f5c5SAndroid Build Coastguard Worker  return '\n'.join(ret)
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Workerdef _AddResources(aar_zip, resource_zips, include_globs):
48*8975f5c5SAndroid Build Coastguard Worker  """Adds all resource zips to the given aar_zip.
49*8975f5c5SAndroid Build Coastguard Worker
50*8975f5c5SAndroid Build Coastguard Worker  Ensures all res/values/* files have unique names by prefixing them.
51*8975f5c5SAndroid Build Coastguard Worker  """
52*8975f5c5SAndroid Build Coastguard Worker  for i, path in enumerate(resource_zips):
53*8975f5c5SAndroid Build Coastguard Worker    if include_globs and not build_utils.MatchesGlob(path, include_globs):
54*8975f5c5SAndroid Build Coastguard Worker      continue
55*8975f5c5SAndroid Build Coastguard Worker    with zipfile.ZipFile(path) as res_zip:
56*8975f5c5SAndroid Build Coastguard Worker      for info in res_zip.infolist():
57*8975f5c5SAndroid Build Coastguard Worker        data = res_zip.read(info)
58*8975f5c5SAndroid Build Coastguard Worker        dirname, basename = posixpath.split(info.filename)
59*8975f5c5SAndroid Build Coastguard Worker        if 'values' in dirname:
60*8975f5c5SAndroid Build Coastguard Worker          root, ext = os.path.splitext(basename)
61*8975f5c5SAndroid Build Coastguard Worker          basename = '{}_{}{}'.format(root, i, ext)
62*8975f5c5SAndroid Build Coastguard Worker          info.filename = posixpath.join(dirname, basename)
63*8975f5c5SAndroid Build Coastguard Worker        info.filename = posixpath.join('res', info.filename)
64*8975f5c5SAndroid Build Coastguard Worker        aar_zip.writestr(info, data)
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Workerdef main(args):
68*8975f5c5SAndroid Build Coastguard Worker  args = build_utils.ExpandFileArgs(args)
69*8975f5c5SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
70*8975f5c5SAndroid Build Coastguard Worker  action_helpers.add_depfile_arg(parser)
71*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--output', required=True, help='Path to output aar.')
72*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--jars', required=True, help='GN list of jar inputs.')
73*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--dependencies-res-zips', required=True,
74*8975f5c5SAndroid Build Coastguard Worker                      help='GN list of resource zips')
75*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--r-text-files', required=True,
76*8975f5c5SAndroid Build Coastguard Worker                      help='GN list of R.txt files to merge')
77*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--proguard-configs', required=True,
78*8975f5c5SAndroid Build Coastguard Worker                      help='GN list of ProGuard flag files to merge.')
79*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
80*8975f5c5SAndroid Build Coastguard Worker      '--android-manifest',
81*8975f5c5SAndroid Build Coastguard Worker      help='Path to AndroidManifest.xml to include.',
82*8975f5c5SAndroid Build Coastguard Worker      default=os.path.join(_ANDROID_BUILD_DIR, 'AndroidManifest.xml'))
83*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--native-libraries', default='',
84*8975f5c5SAndroid Build Coastguard Worker                      help='GN list of native libraries. If non-empty then '
85*8975f5c5SAndroid Build Coastguard Worker                      'ABI must be specified.')
86*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--abi',
87*8975f5c5SAndroid Build Coastguard Worker                      help='ABI (e.g. armeabi-v7a) for native libraries.')
88*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
89*8975f5c5SAndroid Build Coastguard Worker      '--jar-excluded-globs',
90*8975f5c5SAndroid Build Coastguard Worker      help='GN-list of globs for paths to exclude in jar.')
91*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
92*8975f5c5SAndroid Build Coastguard Worker      '--jar-included-globs',
93*8975f5c5SAndroid Build Coastguard Worker      help='GN-list of globs for paths to include in jar.')
94*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
95*8975f5c5SAndroid Build Coastguard Worker      '--resource-included-globs',
96*8975f5c5SAndroid Build Coastguard Worker      help='GN-list of globs for paths to include in R.txt and resources zips.')
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker  options = parser.parse_args(args)
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker  if options.native_libraries and not options.abi:
101*8975f5c5SAndroid Build Coastguard Worker    parser.error('You must provide --abi if you have native libs')
102*8975f5c5SAndroid Build Coastguard Worker
103*8975f5c5SAndroid Build Coastguard Worker  options.jars = action_helpers.parse_gn_list(options.jars)
104*8975f5c5SAndroid Build Coastguard Worker  options.dependencies_res_zips = action_helpers.parse_gn_list(
105*8975f5c5SAndroid Build Coastguard Worker      options.dependencies_res_zips)
106*8975f5c5SAndroid Build Coastguard Worker  options.r_text_files = action_helpers.parse_gn_list(options.r_text_files)
107*8975f5c5SAndroid Build Coastguard Worker  options.proguard_configs = action_helpers.parse_gn_list(
108*8975f5c5SAndroid Build Coastguard Worker      options.proguard_configs)
109*8975f5c5SAndroid Build Coastguard Worker  options.native_libraries = action_helpers.parse_gn_list(
110*8975f5c5SAndroid Build Coastguard Worker      options.native_libraries)
111*8975f5c5SAndroid Build Coastguard Worker  options.jar_excluded_globs = action_helpers.parse_gn_list(
112*8975f5c5SAndroid Build Coastguard Worker      options.jar_excluded_globs)
113*8975f5c5SAndroid Build Coastguard Worker  options.jar_included_globs = action_helpers.parse_gn_list(
114*8975f5c5SAndroid Build Coastguard Worker      options.jar_included_globs)
115*8975f5c5SAndroid Build Coastguard Worker  options.resource_included_globs = action_helpers.parse_gn_list(
116*8975f5c5SAndroid Build Coastguard Worker      options.resource_included_globs)
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker  with tempfile.NamedTemporaryFile(delete=False) as staging_file:
119*8975f5c5SAndroid Build Coastguard Worker    try:
120*8975f5c5SAndroid Build Coastguard Worker      with zipfile.ZipFile(staging_file.name, 'w') as z:
121*8975f5c5SAndroid Build Coastguard Worker        zip_helpers.add_to_zip_hermetic(z,
122*8975f5c5SAndroid Build Coastguard Worker                                        'AndroidManifest.xml',
123*8975f5c5SAndroid Build Coastguard Worker                                        src_path=options.android_manifest)
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker        path_transform = filter_zip.CreatePathTransform(
126*8975f5c5SAndroid Build Coastguard Worker            options.jar_excluded_globs, options.jar_included_globs)
127*8975f5c5SAndroid Build Coastguard Worker        with tempfile.NamedTemporaryFile() as jar_file:
128*8975f5c5SAndroid Build Coastguard Worker          zip_helpers.merge_zips(jar_file.name,
129*8975f5c5SAndroid Build Coastguard Worker                                 options.jars,
130*8975f5c5SAndroid Build Coastguard Worker                                 path_transform=path_transform)
131*8975f5c5SAndroid Build Coastguard Worker          zip_helpers.add_to_zip_hermetic(z,
132*8975f5c5SAndroid Build Coastguard Worker                                          'classes.jar',
133*8975f5c5SAndroid Build Coastguard Worker                                          src_path=jar_file.name)
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker        zip_helpers.add_to_zip_hermetic(z,
136*8975f5c5SAndroid Build Coastguard Worker                                        'R.txt',
137*8975f5c5SAndroid Build Coastguard Worker                                        data=_MergeRTxt(
138*8975f5c5SAndroid Build Coastguard Worker                                            options.r_text_files,
139*8975f5c5SAndroid Build Coastguard Worker                                            options.resource_included_globs))
140*8975f5c5SAndroid Build Coastguard Worker        zip_helpers.add_to_zip_hermetic(z, 'public.txt', data='')
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker        if options.proguard_configs:
143*8975f5c5SAndroid Build Coastguard Worker          zip_helpers.add_to_zip_hermetic(z,
144*8975f5c5SAndroid Build Coastguard Worker                                          'proguard.txt',
145*8975f5c5SAndroid Build Coastguard Worker                                          data=_MergeProguardConfigs(
146*8975f5c5SAndroid Build Coastguard Worker                                              options.proguard_configs))
147*8975f5c5SAndroid Build Coastguard Worker
148*8975f5c5SAndroid Build Coastguard Worker        _AddResources(z, options.dependencies_res_zips,
149*8975f5c5SAndroid Build Coastguard Worker                      options.resource_included_globs)
150*8975f5c5SAndroid Build Coastguard Worker
151*8975f5c5SAndroid Build Coastguard Worker        for native_library in options.native_libraries:
152*8975f5c5SAndroid Build Coastguard Worker          libname = os.path.basename(native_library)
153*8975f5c5SAndroid Build Coastguard Worker          zip_helpers.add_to_zip_hermetic(z,
154*8975f5c5SAndroid Build Coastguard Worker                                          os.path.join('jni', options.abi,
155*8975f5c5SAndroid Build Coastguard Worker                                                       libname),
156*8975f5c5SAndroid Build Coastguard Worker                                          src_path=native_library)
157*8975f5c5SAndroid Build Coastguard Worker    except:
158*8975f5c5SAndroid Build Coastguard Worker      os.unlink(staging_file.name)
159*8975f5c5SAndroid Build Coastguard Worker      raise
160*8975f5c5SAndroid Build Coastguard Worker    shutil.move(staging_file.name, options.output)
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker  if options.depfile:
163*8975f5c5SAndroid Build Coastguard Worker    all_inputs = (options.jars + options.dependencies_res_zips +
164*8975f5c5SAndroid Build Coastguard Worker                  options.r_text_files + options.proguard_configs)
165*8975f5c5SAndroid Build Coastguard Worker    action_helpers.write_depfile(options.depfile, options.output, all_inputs)
166*8975f5c5SAndroid Build Coastguard Worker
167*8975f5c5SAndroid Build Coastguard Worker
168*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
169*8975f5c5SAndroid Build Coastguard Worker  main(sys.argv[1:])
170