xref: /aosp_15_r20/external/angle/build/android/gyp/apkbuilder.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker#
3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2015 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"""Adds the code parts to a resource APK."""
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Workerimport argparse
10*8975f5c5SAndroid Build Coastguard Workerimport logging
11*8975f5c5SAndroid Build Coastguard Workerimport os
12*8975f5c5SAndroid Build Coastguard Workerimport posixpath
13*8975f5c5SAndroid Build Coastguard Workerimport shutil
14*8975f5c5SAndroid Build Coastguard Workerimport sys
15*8975f5c5SAndroid Build Coastguard Workerimport tempfile
16*8975f5c5SAndroid Build Coastguard Workerimport zipfile
17*8975f5c5SAndroid Build Coastguard Workerimport zlib
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Workerimport finalize_apk
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils
22*8975f5c5SAndroid Build Coastguard Workerfrom util import diff_utils
23*8975f5c5SAndroid Build Coastguard Workerimport action_helpers  # build_utils adds //build to sys.path.
24*8975f5c5SAndroid Build Coastguard Workerimport zip_helpers
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker# Taken from aapt's Package.cpp:
28*8975f5c5SAndroid Build Coastguard Worker_NO_COMPRESS_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.gif', '.wav', '.mp2',
29*8975f5c5SAndroid Build Coastguard Worker                           '.mp3', '.ogg', '.aac', '.mpg', '.mpeg', '.mid',
30*8975f5c5SAndroid Build Coastguard Worker                           '.midi', '.smf', '.jet', '.rtttl', '.imy', '.xmf',
31*8975f5c5SAndroid Build Coastguard Worker                           '.mp4', '.m4a', '.m4v', '.3gp', '.3gpp', '.3g2',
32*8975f5c5SAndroid Build Coastguard Worker                           '.3gpp2', '.amr', '.awb', '.wma', '.wmv', '.webm')
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Workerdef _ParseArgs(args):
36*8975f5c5SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
37*8975f5c5SAndroid Build Coastguard Worker  action_helpers.add_depfile_arg(parser)
38*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--assets',
39*8975f5c5SAndroid Build Coastguard Worker                      action='append',
40*8975f5c5SAndroid Build Coastguard Worker                      help='GYP-list of files to add as assets in the form '
41*8975f5c5SAndroid Build Coastguard Worker                      '"srcPath:zipPath", where ":zipPath" is optional.')
42*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
43*8975f5c5SAndroid Build Coastguard Worker      '--java-resources', help='GYP-list of java_resources JARs to include.')
44*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--write-asset-list',
45*8975f5c5SAndroid Build Coastguard Worker                      action='store_true',
46*8975f5c5SAndroid Build Coastguard Worker                      help='Whether to create an assets/assets_list file.')
47*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
48*8975f5c5SAndroid Build Coastguard Worker      '--uncompressed-assets',
49*8975f5c5SAndroid Build Coastguard Worker      help='Same as --assets, except disables compression.')
50*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--resource-apk',
51*8975f5c5SAndroid Build Coastguard Worker                      help='An .ap_ file built using aapt',
52*8975f5c5SAndroid Build Coastguard Worker                      required=True)
53*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--output-apk',
54*8975f5c5SAndroid Build Coastguard Worker                      help='Path to the output file',
55*8975f5c5SAndroid Build Coastguard Worker                      required=True)
56*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--format', choices=['apk', 'bundle-module'],
57*8975f5c5SAndroid Build Coastguard Worker                      default='apk', help='Specify output format.')
58*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--dex-file',
59*8975f5c5SAndroid Build Coastguard Worker                      help='Path to the classes.dex to use')
60*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--uncompress-dex', action='store_true',
61*8975f5c5SAndroid Build Coastguard Worker                      help='Store .dex files uncompressed in the APK')
62*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--native-libs',
63*8975f5c5SAndroid Build Coastguard Worker                      action='append',
64*8975f5c5SAndroid Build Coastguard Worker                      help='GYP-list of native libraries to include. '
65*8975f5c5SAndroid Build Coastguard Worker                           'Can be specified multiple times.',
66*8975f5c5SAndroid Build Coastguard Worker                      default=[])
67*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--secondary-native-libs',
68*8975f5c5SAndroid Build Coastguard Worker                      action='append',
69*8975f5c5SAndroid Build Coastguard Worker                      help='GYP-list of native libraries for secondary '
70*8975f5c5SAndroid Build Coastguard Worker                           'android-abi. Can be specified multiple times.',
71*8975f5c5SAndroid Build Coastguard Worker                      default=[])
72*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--android-abi',
73*8975f5c5SAndroid Build Coastguard Worker                      help='Android architecture to use for native libraries')
74*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--secondary-android-abi',
75*8975f5c5SAndroid Build Coastguard Worker                      help='The secondary Android architecture to use for'
76*8975f5c5SAndroid Build Coastguard Worker                           'secondary native libraries')
77*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
78*8975f5c5SAndroid Build Coastguard Worker      '--is-multi-abi',
79*8975f5c5SAndroid Build Coastguard Worker      action='store_true',
80*8975f5c5SAndroid Build Coastguard Worker      help='Will add a placeholder for the missing ABI if no native libs or '
81*8975f5c5SAndroid Build Coastguard Worker      'placeholders are set for either the primary or secondary ABI. Can only '
82*8975f5c5SAndroid Build Coastguard Worker      'be set if both --android-abi and --secondary-android-abi are set.')
83*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
84*8975f5c5SAndroid Build Coastguard Worker      '--native-lib-placeholders',
85*8975f5c5SAndroid Build Coastguard Worker      help='GYP-list of native library placeholders to add.')
86*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
87*8975f5c5SAndroid Build Coastguard Worker      '--secondary-native-lib-placeholders',
88*8975f5c5SAndroid Build Coastguard Worker      help='GYP-list of native library placeholders to add '
89*8975f5c5SAndroid Build Coastguard Worker      'for the secondary ABI')
90*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--uncompress-shared-libraries', default='False',
91*8975f5c5SAndroid Build Coastguard Worker      choices=['true', 'True', 'false', 'False'],
92*8975f5c5SAndroid Build Coastguard Worker      help='Whether to uncompress native shared libraries. Argument must be '
93*8975f5c5SAndroid Build Coastguard Worker           'a boolean value.')
94*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
95*8975f5c5SAndroid Build Coastguard Worker      '--apksigner-jar', help='Path to the apksigner executable.')
96*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--zipalign-path',
97*8975f5c5SAndroid Build Coastguard Worker                      help='Path to the zipalign executable.')
98*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--key-path',
99*8975f5c5SAndroid Build Coastguard Worker                      help='Path to keystore for signing.')
100*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--key-passwd',
101*8975f5c5SAndroid Build Coastguard Worker                      help='Keystore password')
102*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--key-name',
103*8975f5c5SAndroid Build Coastguard Worker                      help='Keystore name')
104*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
105*8975f5c5SAndroid Build Coastguard Worker      '--min-sdk-version', required=True, help='Value of APK\'s minSdkVersion')
106*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
107*8975f5c5SAndroid Build Coastguard Worker      '--best-compression',
108*8975f5c5SAndroid Build Coastguard Worker      action='store_true',
109*8975f5c5SAndroid Build Coastguard Worker      help='Use zip -9 rather than zip -1')
110*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument(
111*8975f5c5SAndroid Build Coastguard Worker      '--library-always-compress',
112*8975f5c5SAndroid Build Coastguard Worker      action='append',
113*8975f5c5SAndroid Build Coastguard Worker      help='The list of library files that we always compress.')
114*8975f5c5SAndroid Build Coastguard Worker  parser.add_argument('--warnings-as-errors',
115*8975f5c5SAndroid Build Coastguard Worker                      action='store_true',
116*8975f5c5SAndroid Build Coastguard Worker                      help='Treat all warnings as errors.')
117*8975f5c5SAndroid Build Coastguard Worker  diff_utils.AddCommandLineFlags(parser)
118*8975f5c5SAndroid Build Coastguard Worker  options = parser.parse_args(args)
119*8975f5c5SAndroid Build Coastguard Worker  options.assets = action_helpers.parse_gn_list(options.assets)
120*8975f5c5SAndroid Build Coastguard Worker  options.uncompressed_assets = action_helpers.parse_gn_list(
121*8975f5c5SAndroid Build Coastguard Worker      options.uncompressed_assets)
122*8975f5c5SAndroid Build Coastguard Worker  options.native_lib_placeholders = action_helpers.parse_gn_list(
123*8975f5c5SAndroid Build Coastguard Worker      options.native_lib_placeholders)
124*8975f5c5SAndroid Build Coastguard Worker  options.secondary_native_lib_placeholders = action_helpers.parse_gn_list(
125*8975f5c5SAndroid Build Coastguard Worker      options.secondary_native_lib_placeholders)
126*8975f5c5SAndroid Build Coastguard Worker  options.java_resources = action_helpers.parse_gn_list(options.java_resources)
127*8975f5c5SAndroid Build Coastguard Worker  options.native_libs = action_helpers.parse_gn_list(options.native_libs)
128*8975f5c5SAndroid Build Coastguard Worker  options.secondary_native_libs = action_helpers.parse_gn_list(
129*8975f5c5SAndroid Build Coastguard Worker      options.secondary_native_libs)
130*8975f5c5SAndroid Build Coastguard Worker  options.library_always_compress = action_helpers.parse_gn_list(
131*8975f5c5SAndroid Build Coastguard Worker      options.library_always_compress)
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker  if not options.android_abi and (options.native_libs or
134*8975f5c5SAndroid Build Coastguard Worker                                  options.native_lib_placeholders):
135*8975f5c5SAndroid Build Coastguard Worker    raise Exception('Must specify --android-abi with --native-libs')
136*8975f5c5SAndroid Build Coastguard Worker  if not options.secondary_android_abi and (options.secondary_native_libs or
137*8975f5c5SAndroid Build Coastguard Worker      options.secondary_native_lib_placeholders):
138*8975f5c5SAndroid Build Coastguard Worker    raise Exception('Must specify --secondary-android-abi with'
139*8975f5c5SAndroid Build Coastguard Worker                    ' --secondary-native-libs')
140*8975f5c5SAndroid Build Coastguard Worker  if options.is_multi_abi and not (options.android_abi
141*8975f5c5SAndroid Build Coastguard Worker                                   and options.secondary_android_abi):
142*8975f5c5SAndroid Build Coastguard Worker    raise Exception('Must specify --is-multi-abi with both --android-abi '
143*8975f5c5SAndroid Build Coastguard Worker                    'and --secondary-android-abi.')
144*8975f5c5SAndroid Build Coastguard Worker  return options
145*8975f5c5SAndroid Build Coastguard Worker
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Workerdef _SplitAssetPath(path):
148*8975f5c5SAndroid Build Coastguard Worker  """Returns (src, dest) given an asset path in the form src[:dest]."""
149*8975f5c5SAndroid Build Coastguard Worker  path_parts = path.split(':')
150*8975f5c5SAndroid Build Coastguard Worker  src_path = path_parts[0]
151*8975f5c5SAndroid Build Coastguard Worker  if len(path_parts) > 1:
152*8975f5c5SAndroid Build Coastguard Worker    dest_path = path_parts[1]
153*8975f5c5SAndroid Build Coastguard Worker  else:
154*8975f5c5SAndroid Build Coastguard Worker    dest_path = os.path.basename(src_path)
155*8975f5c5SAndroid Build Coastguard Worker  return src_path, dest_path
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Workerdef _ExpandPaths(paths):
159*8975f5c5SAndroid Build Coastguard Worker  """Converts src:dst into tuples and enumerates files within directories.
160*8975f5c5SAndroid Build Coastguard Worker
161*8975f5c5SAndroid Build Coastguard Worker  Args:
162*8975f5c5SAndroid Build Coastguard Worker    paths: Paths in the form "src_path:dest_path"
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker  Returns:
165*8975f5c5SAndroid Build Coastguard Worker    A list of (src_path, dest_path) tuples sorted by dest_path (for stable
166*8975f5c5SAndroid Build Coastguard Worker    ordering within output .apk).
167*8975f5c5SAndroid Build Coastguard Worker  """
168*8975f5c5SAndroid Build Coastguard Worker  ret = []
169*8975f5c5SAndroid Build Coastguard Worker  for path in paths:
170*8975f5c5SAndroid Build Coastguard Worker    src_path, dest_path = _SplitAssetPath(path)
171*8975f5c5SAndroid Build Coastguard Worker    if os.path.isdir(src_path):
172*8975f5c5SAndroid Build Coastguard Worker      for f in build_utils.FindInDirectory(src_path, '*'):
173*8975f5c5SAndroid Build Coastguard Worker        ret.append((f, os.path.join(dest_path, f[len(src_path) + 1:])))
174*8975f5c5SAndroid Build Coastguard Worker    else:
175*8975f5c5SAndroid Build Coastguard Worker      ret.append((src_path, dest_path))
176*8975f5c5SAndroid Build Coastguard Worker  ret.sort(key=lambda t:t[1])
177*8975f5c5SAndroid Build Coastguard Worker  return ret
178*8975f5c5SAndroid Build Coastguard Worker
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Workerdef _GetAssetsToAdd(path_tuples,
181*8975f5c5SAndroid Build Coastguard Worker                    fast_align,
182*8975f5c5SAndroid Build Coastguard Worker                    disable_compression=False,
183*8975f5c5SAndroid Build Coastguard Worker                    allow_reads=True,
184*8975f5c5SAndroid Build Coastguard Worker                    apk_root_dir=''):
185*8975f5c5SAndroid Build Coastguard Worker  """Returns the list of file_detail tuples for assets in the apk.
186*8975f5c5SAndroid Build Coastguard Worker
187*8975f5c5SAndroid Build Coastguard Worker  Args:
188*8975f5c5SAndroid Build Coastguard Worker    path_tuples: List of src_path, dest_path tuples to add.
189*8975f5c5SAndroid Build Coastguard Worker    fast_align: Whether to perform alignment in python zipfile (alternatively
190*8975f5c5SAndroid Build Coastguard Worker                alignment can be done using the zipalign utility out of band).
191*8975f5c5SAndroid Build Coastguard Worker    disable_compression: Whether to disable compression.
192*8975f5c5SAndroid Build Coastguard Worker    allow_reads: If false, we do not try to read the files from disk (to find
193*8975f5c5SAndroid Build Coastguard Worker                 their size for example).
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker  Returns: A list of (src_path, apk_path, compress, alignment) tuple
196*8975f5c5SAndroid Build Coastguard Worker  representing what and how assets are added.
197*8975f5c5SAndroid Build Coastguard Worker  """
198*8975f5c5SAndroid Build Coastguard Worker  assets_to_add = []
199*8975f5c5SAndroid Build Coastguard Worker
200*8975f5c5SAndroid Build Coastguard Worker  # Group all uncompressed assets together in the hope that it will increase
201*8975f5c5SAndroid Build Coastguard Worker  # locality of mmap'ed files.
202*8975f5c5SAndroid Build Coastguard Worker  for target_compress in (False, True):
203*8975f5c5SAndroid Build Coastguard Worker    for src_path, dest_path in path_tuples:
204*8975f5c5SAndroid Build Coastguard Worker      compress = not disable_compression and (
205*8975f5c5SAndroid Build Coastguard Worker          os.path.splitext(src_path)[1] not in _NO_COMPRESS_EXTENSIONS)
206*8975f5c5SAndroid Build Coastguard Worker
207*8975f5c5SAndroid Build Coastguard Worker      if target_compress == compress:
208*8975f5c5SAndroid Build Coastguard Worker        # add_to_zip_hermetic() uses this logic to avoid growing small files.
209*8975f5c5SAndroid Build Coastguard Worker        # We need it here in order to set alignment correctly.
210*8975f5c5SAndroid Build Coastguard Worker        if allow_reads and compress and os.path.getsize(src_path) < 16:
211*8975f5c5SAndroid Build Coastguard Worker          compress = False
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker        if dest_path.startswith('../'):
214*8975f5c5SAndroid Build Coastguard Worker          # posixpath.join('', 'foo') == 'foo'
215*8975f5c5SAndroid Build Coastguard Worker          apk_path = posixpath.join(apk_root_dir, dest_path[3:])
216*8975f5c5SAndroid Build Coastguard Worker        else:
217*8975f5c5SAndroid Build Coastguard Worker          apk_path = 'assets/' + dest_path
218*8975f5c5SAndroid Build Coastguard Worker        alignment = 0 if compress and not fast_align else 4
219*8975f5c5SAndroid Build Coastguard Worker        assets_to_add.append((apk_path, src_path, compress, alignment))
220*8975f5c5SAndroid Build Coastguard Worker  return assets_to_add
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker
223*8975f5c5SAndroid Build Coastguard Workerdef _AddFiles(apk, details):
224*8975f5c5SAndroid Build Coastguard Worker  """Adds files to the apk.
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Worker  Args:
227*8975f5c5SAndroid Build Coastguard Worker    apk: path to APK to add to.
228*8975f5c5SAndroid Build Coastguard Worker    details: A list of file detail tuples (src_path, apk_path, compress,
229*8975f5c5SAndroid Build Coastguard Worker    alignment) representing what and how files are added to the APK.
230*8975f5c5SAndroid Build Coastguard Worker  """
231*8975f5c5SAndroid Build Coastguard Worker  for apk_path, src_path, compress, alignment in details:
232*8975f5c5SAndroid Build Coastguard Worker    # This check is only relevant for assets, but it should not matter if it is
233*8975f5c5SAndroid Build Coastguard Worker    # checked for the whole list of files.
234*8975f5c5SAndroid Build Coastguard Worker    try:
235*8975f5c5SAndroid Build Coastguard Worker      apk.getinfo(apk_path)
236*8975f5c5SAndroid Build Coastguard Worker      # Should never happen since write_build_config.py handles merging.
237*8975f5c5SAndroid Build Coastguard Worker      raise Exception(
238*8975f5c5SAndroid Build Coastguard Worker          'Multiple targets specified the asset path: %s' % apk_path)
239*8975f5c5SAndroid Build Coastguard Worker    except KeyError:
240*8975f5c5SAndroid Build Coastguard Worker      zip_helpers.add_to_zip_hermetic(apk,
241*8975f5c5SAndroid Build Coastguard Worker                                      apk_path,
242*8975f5c5SAndroid Build Coastguard Worker                                      src_path=src_path,
243*8975f5c5SAndroid Build Coastguard Worker                                      compress=compress,
244*8975f5c5SAndroid Build Coastguard Worker                                      alignment=alignment)
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Worker
247*8975f5c5SAndroid Build Coastguard Workerdef _GetAbiAlignment(android_abi):
248*8975f5c5SAndroid Build Coastguard Worker  if '64' in android_abi:
249*8975f5c5SAndroid Build Coastguard Worker    return 0x4000  # 16k alignment
250*8975f5c5SAndroid Build Coastguard Worker  return 0x1000  # 4k alignment
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker
253*8975f5c5SAndroid Build Coastguard Workerdef _GetNativeLibrariesToAdd(native_libs, android_abi, fast_align,
254*8975f5c5SAndroid Build Coastguard Worker                             lib_always_compress):
255*8975f5c5SAndroid Build Coastguard Worker  """Returns the list of file_detail tuples for native libraries in the apk.
256*8975f5c5SAndroid Build Coastguard Worker
257*8975f5c5SAndroid Build Coastguard Worker  Returns: A list of (src_path, apk_path, compress, alignment) tuple
258*8975f5c5SAndroid Build Coastguard Worker  representing what and how native libraries are added.
259*8975f5c5SAndroid Build Coastguard Worker  """
260*8975f5c5SAndroid Build Coastguard Worker  libraries_to_add = []
261*8975f5c5SAndroid Build Coastguard Worker
262*8975f5c5SAndroid Build Coastguard Worker
263*8975f5c5SAndroid Build Coastguard Worker  for path in native_libs:
264*8975f5c5SAndroid Build Coastguard Worker    basename = os.path.basename(path)
265*8975f5c5SAndroid Build Coastguard Worker    compress = any(lib_name in basename for lib_name in lib_always_compress)
266*8975f5c5SAndroid Build Coastguard Worker    lib_android_abi = android_abi
267*8975f5c5SAndroid Build Coastguard Worker    if path.startswith('android_clang_arm64_hwasan/'):
268*8975f5c5SAndroid Build Coastguard Worker      lib_android_abi = 'arm64-v8a-hwasan'
269*8975f5c5SAndroid Build Coastguard Worker
270*8975f5c5SAndroid Build Coastguard Worker    apk_path = 'lib/%s/%s' % (lib_android_abi, basename)
271*8975f5c5SAndroid Build Coastguard Worker    if compress and not fast_align:
272*8975f5c5SAndroid Build Coastguard Worker      alignment = 0
273*8975f5c5SAndroid Build Coastguard Worker    else:
274*8975f5c5SAndroid Build Coastguard Worker      alignment = _GetAbiAlignment(android_abi)
275*8975f5c5SAndroid Build Coastguard Worker    libraries_to_add.append((apk_path, path, compress, alignment))
276*8975f5c5SAndroid Build Coastguard Worker
277*8975f5c5SAndroid Build Coastguard Worker  return libraries_to_add
278*8975f5c5SAndroid Build Coastguard Worker
279*8975f5c5SAndroid Build Coastguard Worker
280*8975f5c5SAndroid Build Coastguard Workerdef _CreateExpectationsData(native_libs, assets):
281*8975f5c5SAndroid Build Coastguard Worker  """Creates list of native libraries and assets."""
282*8975f5c5SAndroid Build Coastguard Worker  native_libs = sorted(native_libs)
283*8975f5c5SAndroid Build Coastguard Worker  assets = sorted(assets)
284*8975f5c5SAndroid Build Coastguard Worker
285*8975f5c5SAndroid Build Coastguard Worker  ret = []
286*8975f5c5SAndroid Build Coastguard Worker  for apk_path, _, compress, alignment in native_libs + assets:
287*8975f5c5SAndroid Build Coastguard Worker    ret.append('apk_path=%s, compress=%s, alignment=%s\n' %
288*8975f5c5SAndroid Build Coastguard Worker               (apk_path, compress, alignment))
289*8975f5c5SAndroid Build Coastguard Worker  return ''.join(ret)
290*8975f5c5SAndroid Build Coastguard Worker
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Workerdef main(args):
293*8975f5c5SAndroid Build Coastguard Worker  build_utils.InitLogging('APKBUILDER_DEBUG')
294*8975f5c5SAndroid Build Coastguard Worker  args = build_utils.ExpandFileArgs(args)
295*8975f5c5SAndroid Build Coastguard Worker  options = _ParseArgs(args)
296*8975f5c5SAndroid Build Coastguard Worker
297*8975f5c5SAndroid Build Coastguard Worker  # Until Python 3.7, there's no better way to set compression level.
298*8975f5c5SAndroid Build Coastguard Worker  # The default is 6.
299*8975f5c5SAndroid Build Coastguard Worker  if options.best_compression:
300*8975f5c5SAndroid Build Coastguard Worker    # Compresses about twice as slow as the default.
301*8975f5c5SAndroid Build Coastguard Worker    zlib.Z_DEFAULT_COMPRESSION = 9
302*8975f5c5SAndroid Build Coastguard Worker  else:
303*8975f5c5SAndroid Build Coastguard Worker    # Compresses about twice as fast as the default.
304*8975f5c5SAndroid Build Coastguard Worker    zlib.Z_DEFAULT_COMPRESSION = 1
305*8975f5c5SAndroid Build Coastguard Worker
306*8975f5c5SAndroid Build Coastguard Worker  # Python's zip implementation duplicates file comments in the central
307*8975f5c5SAndroid Build Coastguard Worker  # directory, whereas zipalign does not, so use zipalign for official builds.
308*8975f5c5SAndroid Build Coastguard Worker  requires_alignment = options.format == 'apk'
309*8975f5c5SAndroid Build Coastguard Worker  # TODO(crbug.com/40286668): Re-enable zipalign once we are using Android V
310*8975f5c5SAndroid Build Coastguard Worker  # SDK.
311*8975f5c5SAndroid Build Coastguard Worker  run_zipalign = requires_alignment and options.best_compression and False
312*8975f5c5SAndroid Build Coastguard Worker  fast_align = bool(requires_alignment and not run_zipalign)
313*8975f5c5SAndroid Build Coastguard Worker
314*8975f5c5SAndroid Build Coastguard Worker  native_libs = sorted(options.native_libs)
315*8975f5c5SAndroid Build Coastguard Worker
316*8975f5c5SAndroid Build Coastguard Worker  # Include native libs in the depfile_deps since GN doesn't know about the
317*8975f5c5SAndroid Build Coastguard Worker  # dependencies when is_component_build=true.
318*8975f5c5SAndroid Build Coastguard Worker  depfile_deps = list(native_libs)
319*8975f5c5SAndroid Build Coastguard Worker
320*8975f5c5SAndroid Build Coastguard Worker  # For targets that depend on static library APKs, dex paths are created by
321*8975f5c5SAndroid Build Coastguard Worker  # the static library's dexsplitter target and GN doesn't know about these
322*8975f5c5SAndroid Build Coastguard Worker  # paths.
323*8975f5c5SAndroid Build Coastguard Worker  if options.dex_file:
324*8975f5c5SAndroid Build Coastguard Worker    depfile_deps.append(options.dex_file)
325*8975f5c5SAndroid Build Coastguard Worker
326*8975f5c5SAndroid Build Coastguard Worker  secondary_native_libs = []
327*8975f5c5SAndroid Build Coastguard Worker  if options.secondary_native_libs:
328*8975f5c5SAndroid Build Coastguard Worker    secondary_native_libs = sorted(options.secondary_native_libs)
329*8975f5c5SAndroid Build Coastguard Worker    depfile_deps += secondary_native_libs
330*8975f5c5SAndroid Build Coastguard Worker
331*8975f5c5SAndroid Build Coastguard Worker  if options.java_resources:
332*8975f5c5SAndroid Build Coastguard Worker    # Included via .build_config.json, so need to write it to depfile.
333*8975f5c5SAndroid Build Coastguard Worker    depfile_deps.extend(options.java_resources)
334*8975f5c5SAndroid Build Coastguard Worker
335*8975f5c5SAndroid Build Coastguard Worker  assets = _ExpandPaths(options.assets)
336*8975f5c5SAndroid Build Coastguard Worker  uncompressed_assets = _ExpandPaths(options.uncompressed_assets)
337*8975f5c5SAndroid Build Coastguard Worker
338*8975f5c5SAndroid Build Coastguard Worker  # Included via .build_config.json, so need to write it to depfile.
339*8975f5c5SAndroid Build Coastguard Worker  depfile_deps.extend(x[0] for x in assets)
340*8975f5c5SAndroid Build Coastguard Worker  depfile_deps.extend(x[0] for x in uncompressed_assets)
341*8975f5c5SAndroid Build Coastguard Worker  depfile_deps.append(options.resource_apk)
342*8975f5c5SAndroid Build Coastguard Worker
343*8975f5c5SAndroid Build Coastguard Worker  # Bundle modules have a structure similar to APKs, except that resources
344*8975f5c5SAndroid Build Coastguard Worker  # are compiled in protobuf format (instead of binary xml), and that some
345*8975f5c5SAndroid Build Coastguard Worker  # files are located into different top-level directories, e.g.:
346*8975f5c5SAndroid Build Coastguard Worker  #  AndroidManifest.xml -> manifest/AndroidManifest.xml
347*8975f5c5SAndroid Build Coastguard Worker  #  classes.dex -> dex/classes.dex
348*8975f5c5SAndroid Build Coastguard Worker  #  res/ -> res/  (unchanged)
349*8975f5c5SAndroid Build Coastguard Worker  #  assets/ -> assets/  (unchanged)
350*8975f5c5SAndroid Build Coastguard Worker  #  <other-file> -> root/<other-file>
351*8975f5c5SAndroid Build Coastguard Worker  #
352*8975f5c5SAndroid Build Coastguard Worker  # Hence, the following variables are used to control the location of files in
353*8975f5c5SAndroid Build Coastguard Worker  # the final archive.
354*8975f5c5SAndroid Build Coastguard Worker  if options.format == 'bundle-module':
355*8975f5c5SAndroid Build Coastguard Worker    apk_manifest_dir = 'manifest/'
356*8975f5c5SAndroid Build Coastguard Worker    apk_root_dir = 'root/'
357*8975f5c5SAndroid Build Coastguard Worker    apk_dex_dir = 'dex/'
358*8975f5c5SAndroid Build Coastguard Worker  else:
359*8975f5c5SAndroid Build Coastguard Worker    apk_manifest_dir = ''
360*8975f5c5SAndroid Build Coastguard Worker    apk_root_dir = ''
361*8975f5c5SAndroid Build Coastguard Worker    apk_dex_dir = ''
362*8975f5c5SAndroid Build Coastguard Worker
363*8975f5c5SAndroid Build Coastguard Worker  def _GetAssetDetails(assets, uncompressed_assets, fast_align, allow_reads):
364*8975f5c5SAndroid Build Coastguard Worker    ret = _GetAssetsToAdd(assets,
365*8975f5c5SAndroid Build Coastguard Worker                          fast_align,
366*8975f5c5SAndroid Build Coastguard Worker                          disable_compression=False,
367*8975f5c5SAndroid Build Coastguard Worker                          allow_reads=allow_reads,
368*8975f5c5SAndroid Build Coastguard Worker                          apk_root_dir=apk_root_dir)
369*8975f5c5SAndroid Build Coastguard Worker    ret.extend(
370*8975f5c5SAndroid Build Coastguard Worker        _GetAssetsToAdd(uncompressed_assets,
371*8975f5c5SAndroid Build Coastguard Worker                        fast_align,
372*8975f5c5SAndroid Build Coastguard Worker                        disable_compression=True,
373*8975f5c5SAndroid Build Coastguard Worker                        allow_reads=allow_reads,
374*8975f5c5SAndroid Build Coastguard Worker                        apk_root_dir=apk_root_dir))
375*8975f5c5SAndroid Build Coastguard Worker    return ret
376*8975f5c5SAndroid Build Coastguard Worker
377*8975f5c5SAndroid Build Coastguard Worker  libs_to_add = _GetNativeLibrariesToAdd(native_libs, options.android_abi,
378*8975f5c5SAndroid Build Coastguard Worker                                         fast_align,
379*8975f5c5SAndroid Build Coastguard Worker                                         options.library_always_compress)
380*8975f5c5SAndroid Build Coastguard Worker  if options.secondary_android_abi:
381*8975f5c5SAndroid Build Coastguard Worker    libs_to_add.extend(
382*8975f5c5SAndroid Build Coastguard Worker        _GetNativeLibrariesToAdd(secondary_native_libs,
383*8975f5c5SAndroid Build Coastguard Worker                                 options.secondary_android_abi,
384*8975f5c5SAndroid Build Coastguard Worker                                 fast_align, options.library_always_compress))
385*8975f5c5SAndroid Build Coastguard Worker
386*8975f5c5SAndroid Build Coastguard Worker  if options.expected_file:
387*8975f5c5SAndroid Build Coastguard Worker    # We compute expectations without reading the files. This allows us to check
388*8975f5c5SAndroid Build Coastguard Worker    # expectations for different targets by just generating their build_configs
389*8975f5c5SAndroid Build Coastguard Worker    # and not have to first generate all the actual files and all their
390*8975f5c5SAndroid Build Coastguard Worker    # dependencies (for example by just passing --only-verify-expectations).
391*8975f5c5SAndroid Build Coastguard Worker    asset_details = _GetAssetDetails(assets,
392*8975f5c5SAndroid Build Coastguard Worker                                     uncompressed_assets,
393*8975f5c5SAndroid Build Coastguard Worker                                     fast_align,
394*8975f5c5SAndroid Build Coastguard Worker                                     allow_reads=False)
395*8975f5c5SAndroid Build Coastguard Worker
396*8975f5c5SAndroid Build Coastguard Worker    actual_data = _CreateExpectationsData(libs_to_add, asset_details)
397*8975f5c5SAndroid Build Coastguard Worker    diff_utils.CheckExpectations(actual_data, options)
398*8975f5c5SAndroid Build Coastguard Worker
399*8975f5c5SAndroid Build Coastguard Worker    if options.only_verify_expectations:
400*8975f5c5SAndroid Build Coastguard Worker      if options.depfile:
401*8975f5c5SAndroid Build Coastguard Worker        action_helpers.write_depfile(options.depfile,
402*8975f5c5SAndroid Build Coastguard Worker                                     options.actual_file,
403*8975f5c5SAndroid Build Coastguard Worker                                     inputs=depfile_deps)
404*8975f5c5SAndroid Build Coastguard Worker      return
405*8975f5c5SAndroid Build Coastguard Worker
406*8975f5c5SAndroid Build Coastguard Worker  # If we are past this point, we are going to actually create the final apk so
407*8975f5c5SAndroid Build Coastguard Worker  # we should recompute asset details again but maybe perform some optimizations
408*8975f5c5SAndroid Build Coastguard Worker  # based on the size of the files on disk.
409*8975f5c5SAndroid Build Coastguard Worker  assets_to_add = _GetAssetDetails(
410*8975f5c5SAndroid Build Coastguard Worker      assets, uncompressed_assets, fast_align, allow_reads=True)
411*8975f5c5SAndroid Build Coastguard Worker
412*8975f5c5SAndroid Build Coastguard Worker  # Targets generally do not depend on apks, so no need for only_if_changed.
413*8975f5c5SAndroid Build Coastguard Worker  with action_helpers.atomic_output(options.output_apk,
414*8975f5c5SAndroid Build Coastguard Worker                                    only_if_changed=False) as f:
415*8975f5c5SAndroid Build Coastguard Worker    with zipfile.ZipFile(options.resource_apk) as resource_apk, \
416*8975f5c5SAndroid Build Coastguard Worker         zipfile.ZipFile(f, 'w') as out_apk:
417*8975f5c5SAndroid Build Coastguard Worker
418*8975f5c5SAndroid Build Coastguard Worker      def add_to_zip(zip_path, data, compress=True, alignment=4):
419*8975f5c5SAndroid Build Coastguard Worker        zip_helpers.add_to_zip_hermetic(
420*8975f5c5SAndroid Build Coastguard Worker            out_apk,
421*8975f5c5SAndroid Build Coastguard Worker            zip_path,
422*8975f5c5SAndroid Build Coastguard Worker            data=data,
423*8975f5c5SAndroid Build Coastguard Worker            compress=compress,
424*8975f5c5SAndroid Build Coastguard Worker            alignment=0 if compress and not fast_align else alignment)
425*8975f5c5SAndroid Build Coastguard Worker
426*8975f5c5SAndroid Build Coastguard Worker      def copy_resource(zipinfo, out_dir=''):
427*8975f5c5SAndroid Build Coastguard Worker        add_to_zip(
428*8975f5c5SAndroid Build Coastguard Worker            out_dir + zipinfo.filename,
429*8975f5c5SAndroid Build Coastguard Worker            resource_apk.read(zipinfo.filename),
430*8975f5c5SAndroid Build Coastguard Worker            compress=zipinfo.compress_type != zipfile.ZIP_STORED)
431*8975f5c5SAndroid Build Coastguard Worker
432*8975f5c5SAndroid Build Coastguard Worker      # Make assets come before resources in order to maintain the same file
433*8975f5c5SAndroid Build Coastguard Worker      # ordering as GYP / aapt. http://crbug.com/561862
434*8975f5c5SAndroid Build Coastguard Worker      resource_infos = resource_apk.infolist()
435*8975f5c5SAndroid Build Coastguard Worker
436*8975f5c5SAndroid Build Coastguard Worker      # 1. AndroidManifest.xml
437*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding AndroidManifest.xml')
438*8975f5c5SAndroid Build Coastguard Worker      copy_resource(
439*8975f5c5SAndroid Build Coastguard Worker          resource_apk.getinfo('AndroidManifest.xml'), out_dir=apk_manifest_dir)
440*8975f5c5SAndroid Build Coastguard Worker
441*8975f5c5SAndroid Build Coastguard Worker      # 2. Assets
442*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding assets/')
443*8975f5c5SAndroid Build Coastguard Worker      _AddFiles(out_apk, assets_to_add)
444*8975f5c5SAndroid Build Coastguard Worker
445*8975f5c5SAndroid Build Coastguard Worker      # 3. DEX and META-INF/services/
446*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding classes.dex')
447*8975f5c5SAndroid Build Coastguard Worker      if options.dex_file:
448*8975f5c5SAndroid Build Coastguard Worker        with open(options.dex_file, 'rb') as dex_file_obj:
449*8975f5c5SAndroid Build Coastguard Worker          if options.dex_file.endswith('.dex'):
450*8975f5c5SAndroid Build Coastguard Worker            # This is the case for incremental_install=true.
451*8975f5c5SAndroid Build Coastguard Worker            add_to_zip(
452*8975f5c5SAndroid Build Coastguard Worker                apk_dex_dir + 'classes.dex',
453*8975f5c5SAndroid Build Coastguard Worker                dex_file_obj.read(),
454*8975f5c5SAndroid Build Coastguard Worker                compress=not options.uncompress_dex)
455*8975f5c5SAndroid Build Coastguard Worker          else:
456*8975f5c5SAndroid Build Coastguard Worker            with zipfile.ZipFile(dex_file_obj) as dex_zip:
457*8975f5c5SAndroid Build Coastguard Worker              # Add META-INF/services.
458*8975f5c5SAndroid Build Coastguard Worker              for name in sorted(dex_zip.namelist()):
459*8975f5c5SAndroid Build Coastguard Worker                if name.startswith('META-INF/services/'):
460*8975f5c5SAndroid Build Coastguard Worker                  # proguard.py does not bundle these files (dex.py does)
461*8975f5c5SAndroid Build Coastguard Worker                  # because R8 optimizes all ServiceLoader calls.
462*8975f5c5SAndroid Build Coastguard Worker                  if options.dex_file.endswith('.r8dex.jar'):
463*8975f5c5SAndroid Build Coastguard Worker                    raise Exception(
464*8975f5c5SAndroid Build Coastguard Worker                        f'Expected no META-INF/services, but found: {name}' +
465*8975f5c5SAndroid Build Coastguard Worker                        f'in {options.dex_file}')
466*8975f5c5SAndroid Build Coastguard Worker                  add_to_zip(apk_root_dir + name,
467*8975f5c5SAndroid Build Coastguard Worker                             dex_zip.read(name),
468*8975f5c5SAndroid Build Coastguard Worker                             compress=False)
469*8975f5c5SAndroid Build Coastguard Worker              # Add classes.dex.
470*8975f5c5SAndroid Build Coastguard Worker              for name in dex_zip.namelist():
471*8975f5c5SAndroid Build Coastguard Worker                if name.endswith('.dex'):
472*8975f5c5SAndroid Build Coastguard Worker                  add_to_zip(apk_dex_dir + name,
473*8975f5c5SAndroid Build Coastguard Worker                             dex_zip.read(name),
474*8975f5c5SAndroid Build Coastguard Worker                             compress=not options.uncompress_dex)
475*8975f5c5SAndroid Build Coastguard Worker
476*8975f5c5SAndroid Build Coastguard Worker      # 4. Native libraries.
477*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding lib/')
478*8975f5c5SAndroid Build Coastguard Worker      _AddFiles(out_apk, libs_to_add)
479*8975f5c5SAndroid Build Coastguard Worker
480*8975f5c5SAndroid Build Coastguard Worker      # Add a placeholder lib if the APK should be multi ABI but is missing libs
481*8975f5c5SAndroid Build Coastguard Worker      # for one of the ABIs.
482*8975f5c5SAndroid Build Coastguard Worker      native_lib_placeholders = options.native_lib_placeholders
483*8975f5c5SAndroid Build Coastguard Worker      secondary_native_lib_placeholders = (
484*8975f5c5SAndroid Build Coastguard Worker          options.secondary_native_lib_placeholders)
485*8975f5c5SAndroid Build Coastguard Worker      if options.is_multi_abi:
486*8975f5c5SAndroid Build Coastguard Worker        if ((secondary_native_libs or secondary_native_lib_placeholders)
487*8975f5c5SAndroid Build Coastguard Worker            and not native_libs and not native_lib_placeholders):
488*8975f5c5SAndroid Build Coastguard Worker          native_lib_placeholders += ['libplaceholder.so']
489*8975f5c5SAndroid Build Coastguard Worker        if ((native_libs or native_lib_placeholders)
490*8975f5c5SAndroid Build Coastguard Worker            and not secondary_native_libs
491*8975f5c5SAndroid Build Coastguard Worker            and not secondary_native_lib_placeholders):
492*8975f5c5SAndroid Build Coastguard Worker          secondary_native_lib_placeholders += ['libplaceholder.so']
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker      # Add placeholder libs.
495*8975f5c5SAndroid Build Coastguard Worker      for name in sorted(native_lib_placeholders):
496*8975f5c5SAndroid Build Coastguard Worker        # Note: Empty libs files are ignored by md5check (can cause issues
497*8975f5c5SAndroid Build Coastguard Worker        # with stale builds when the only change is adding/removing
498*8975f5c5SAndroid Build Coastguard Worker        # placeholders).
499*8975f5c5SAndroid Build Coastguard Worker        apk_path = 'lib/%s/%s' % (options.android_abi, name)
500*8975f5c5SAndroid Build Coastguard Worker        alignment = _GetAbiAlignment(options.android_abi)
501*8975f5c5SAndroid Build Coastguard Worker        add_to_zip(apk_path, '', alignment=alignment)
502*8975f5c5SAndroid Build Coastguard Worker
503*8975f5c5SAndroid Build Coastguard Worker      for name in sorted(secondary_native_lib_placeholders):
504*8975f5c5SAndroid Build Coastguard Worker        # Note: Empty libs files are ignored by md5check (can cause issues
505*8975f5c5SAndroid Build Coastguard Worker        # with stale builds when the only change is adding/removing
506*8975f5c5SAndroid Build Coastguard Worker        # placeholders).
507*8975f5c5SAndroid Build Coastguard Worker        apk_path = 'lib/%s/%s' % (options.secondary_android_abi, name)
508*8975f5c5SAndroid Build Coastguard Worker        alignment = _GetAbiAlignment(options.secondary_android_abi)
509*8975f5c5SAndroid Build Coastguard Worker        add_to_zip(apk_path, '', alignment=alignment)
510*8975f5c5SAndroid Build Coastguard Worker
511*8975f5c5SAndroid Build Coastguard Worker      # 5. Resources
512*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding res/')
513*8975f5c5SAndroid Build Coastguard Worker      for info in sorted(resource_infos, key=lambda i: i.filename):
514*8975f5c5SAndroid Build Coastguard Worker        if info.filename != 'AndroidManifest.xml':
515*8975f5c5SAndroid Build Coastguard Worker          copy_resource(info)
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker      # 6. Java resources that should be accessible via
518*8975f5c5SAndroid Build Coastguard Worker      # Class.getResourceAsStream(), in particular parts of Emma jar.
519*8975f5c5SAndroid Build Coastguard Worker      # Prebuilt jars may contain class files which we shouldn't include.
520*8975f5c5SAndroid Build Coastguard Worker      logging.debug('Adding Java resources')
521*8975f5c5SAndroid Build Coastguard Worker      for java_resource in options.java_resources:
522*8975f5c5SAndroid Build Coastguard Worker        with zipfile.ZipFile(java_resource, 'r') as java_resource_jar:
523*8975f5c5SAndroid Build Coastguard Worker          for apk_path in sorted(java_resource_jar.namelist()):
524*8975f5c5SAndroid Build Coastguard Worker            apk_path_lower = apk_path.lower()
525*8975f5c5SAndroid Build Coastguard Worker
526*8975f5c5SAndroid Build Coastguard Worker            if apk_path_lower.startswith('meta-inf/'):
527*8975f5c5SAndroid Build Coastguard Worker              continue
528*8975f5c5SAndroid Build Coastguard Worker            if apk_path_lower.endswith('/'):
529*8975f5c5SAndroid Build Coastguard Worker              continue
530*8975f5c5SAndroid Build Coastguard Worker            if apk_path_lower.endswith('.class'):
531*8975f5c5SAndroid Build Coastguard Worker              continue
532*8975f5c5SAndroid Build Coastguard Worker
533*8975f5c5SAndroid Build Coastguard Worker            add_to_zip(apk_root_dir + apk_path,
534*8975f5c5SAndroid Build Coastguard Worker                       java_resource_jar.read(apk_path))
535*8975f5c5SAndroid Build Coastguard Worker
536*8975f5c5SAndroid Build Coastguard Worker    if options.format == 'apk' and options.key_path:
537*8975f5c5SAndroid Build Coastguard Worker      zipalign_path = None if fast_align else options.zipalign_path
538*8975f5c5SAndroid Build Coastguard Worker      finalize_apk.FinalizeApk(options.apksigner_jar,
539*8975f5c5SAndroid Build Coastguard Worker                               zipalign_path,
540*8975f5c5SAndroid Build Coastguard Worker                               f.name,
541*8975f5c5SAndroid Build Coastguard Worker                               f.name,
542*8975f5c5SAndroid Build Coastguard Worker                               options.key_path,
543*8975f5c5SAndroid Build Coastguard Worker                               options.key_passwd,
544*8975f5c5SAndroid Build Coastguard Worker                               options.key_name,
545*8975f5c5SAndroid Build Coastguard Worker                               int(options.min_sdk_version),
546*8975f5c5SAndroid Build Coastguard Worker                               warnings_as_errors=options.warnings_as_errors)
547*8975f5c5SAndroid Build Coastguard Worker    logging.debug('Moving file into place')
548*8975f5c5SAndroid Build Coastguard Worker
549*8975f5c5SAndroid Build Coastguard Worker    if options.depfile:
550*8975f5c5SAndroid Build Coastguard Worker      action_helpers.write_depfile(options.depfile,
551*8975f5c5SAndroid Build Coastguard Worker                                   options.output_apk,
552*8975f5c5SAndroid Build Coastguard Worker                                   inputs=depfile_deps)
553*8975f5c5SAndroid Build Coastguard Worker
554*8975f5c5SAndroid Build Coastguard Worker
555*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
556*8975f5c5SAndroid Build Coastguard Worker  main(sys.argv[1:])
557