Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: build/android/gyp/finalize_apk.py

Issue 2629663003: Reland of Android: Delete rezip in favor of zipalign -p (Closed)
Patch Set: no gdbserver Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/gyp/apkbuilder.py ('k') | build/android/rezip/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved. 3 # Copyright 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 """Signs and zipaligns APK. 6 """Signs and zipaligns APK.
7 7
8 """ 8 """
9 9
10 import optparse 10 import optparse
11 import os 11 import os
12 import shutil 12 import shutil
13 import sys 13 import sys
14 import tempfile 14 import tempfile
15 import zipfile 15 import zipfile
16 16
17 # resource_sizes modifies zipfile for zip64 compatibility. See 17 # resource_sizes modifies zipfile for zip64 compatibility. See
18 # https://bugs.python.org/issue14315. 18 # https://bugs.python.org/issue14315.
19 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) 19 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
20 import resource_sizes # pylint: disable=unused-import 20 import resource_sizes # pylint: disable=unused-import
21 21
22 from util import build_utils 22 from util import build_utils
23 23
24 def RenameInflateAndAddPageAlignment(
25 rezip_apk_jar_path, in_zip_file, out_zip_file):
26 rezip_apk_cmd = [
27 'java',
28 '-classpath',
29 rezip_apk_jar_path,
30 'RezipApk',
31 'renamealign',
32 in_zip_file,
33 out_zip_file,
34 ]
35 build_utils.CheckOutput(rezip_apk_cmd)
36
37
38 def ReorderAndAlignApk(rezip_apk_jar_path, in_zip_file, out_zip_file):
39 rezip_apk_cmd = [
40 'java',
41 '-classpath',
42 rezip_apk_jar_path,
43 'RezipApk',
44 'reorder',
45 in_zip_file,
46 out_zip_file,
47 ]
48 build_utils.CheckOutput(rezip_apk_cmd)
49
50 24
51 def JarSigner(key_path, key_name, key_passwd, unsigned_path, signed_path): 25 def JarSigner(key_path, key_name, key_passwd, unsigned_path, signed_path):
52 shutil.copy(unsigned_path, signed_path) 26 shutil.copy(unsigned_path, signed_path)
53 sign_cmd = [ 27 sign_cmd = [
54 'jarsigner', 28 'jarsigner',
55 '-sigalg', 'MD5withRSA', 29 '-sigalg', 'MD5withRSA',
56 '-digestalg', 'SHA1', 30 '-digestalg', 'SHA1',
57 '-keystore', key_path, 31 '-keystore', key_path,
58 '-storepass', key_passwd, 32 '-storepass', key_passwd,
59 signed_path, 33 signed_path,
60 key_name, 34 key_name,
61 ] 35 ]
62 build_utils.CheckOutput(sign_cmd) 36 build_utils.CheckOutput(sign_cmd)
63 37
64 38
65 def AlignApk(zipalign_path, package_align, unaligned_path, final_path): 39 def AlignApk(zipalign_path, unaligned_path, final_path):
40 # Note -p will page align native libraries (files ending with .so), but
41 # only those that are stored uncompressed.
66 align_cmd = [ 42 align_cmd = [
67 zipalign_path, 43 zipalign_path,
68 '-f' 44 '-p',
45 '-f',
69 ] 46 ]
70 47
71 if package_align:
72 align_cmd += ['-p']
73 48
74 align_cmd += [ 49 align_cmd += [
75 '4', # 4 bytes 50 '4', # 4 bytes
76 unaligned_path, 51 unaligned_path,
77 final_path, 52 final_path,
78 ] 53 ]
79 build_utils.CheckOutput(align_cmd) 54 build_utils.CheckOutput(align_cmd)
80 55
81 56
82 def main(args): 57 def main(args):
83 args = build_utils.ExpandFileArgs(args) 58 args = build_utils.ExpandFileArgs(args)
84 59
85 parser = optparse.OptionParser() 60 parser = optparse.OptionParser()
86 build_utils.AddDepfileOption(parser) 61 build_utils.AddDepfileOption(parser)
87 62
88 parser.add_option('--rezip-apk-jar-path',
89 help='Path to the RezipApk jar file.')
90 parser.add_option('--zipalign-path', help='Path to the zipalign tool.') 63 parser.add_option('--zipalign-path', help='Path to the zipalign tool.')
91 parser.add_option('--page-align-shared-libraries',
92 action='store_true',
93 help='Page align shared libraries.')
94 parser.add_option('--unsigned-apk-path', help='Path to input unsigned APK.') 64 parser.add_option('--unsigned-apk-path', help='Path to input unsigned APK.')
95 parser.add_option('--final-apk-path', 65 parser.add_option('--final-apk-path',
96 help='Path to output signed and aligned APK.') 66 help='Path to output signed and aligned APK.')
97 parser.add_option('--key-path', help='Path to keystore for signing.') 67 parser.add_option('--key-path', help='Path to keystore for signing.')
98 parser.add_option('--key-passwd', help='Keystore password') 68 parser.add_option('--key-passwd', help='Keystore password')
99 parser.add_option('--key-name', help='Keystore name') 69 parser.add_option('--key-name', help='Keystore name')
100 parser.add_option('--stamp', help='Path to touch on success.')
101 parser.add_option('--load-library-from-zip', type='int',
102 help='If non-zero, build the APK such that the library can be loaded ' +
103 'directly from the zip file using the crazy linker. The library ' +
104 'will be renamed, uncompressed and page aligned.')
105 70
106 options, _ = parser.parse_args() 71 options, _ = parser.parse_args()
107 72
108 input_paths = [ 73 input_paths = [
109 options.unsigned_apk_path, 74 options.unsigned_apk_path,
110 options.key_path, 75 options.key_path,
111 ] 76 ]
112 77
113 if options.load_library_from_zip:
114 input_paths.append(options.rezip_apk_jar_path)
115
116 input_strings = [ 78 input_strings = [
117 options.load_library_from_zip,
118 options.key_name, 79 options.key_name,
119 options.key_passwd, 80 options.key_passwd,
120 options.page_align_shared_libraries,
121 ] 81 ]
122 82
123 build_utils.CallAndWriteDepfileIfStale( 83 build_utils.CallAndWriteDepfileIfStale(
124 lambda: FinalizeApk(options), 84 lambda: FinalizeApk(options),
125 options, 85 options,
126 record_path=options.unsigned_apk_path + '.finalize.md5.stamp', 86 record_path=options.unsigned_apk_path + '.finalize.md5.stamp',
127 input_paths=input_paths, 87 input_paths=input_paths,
128 input_strings=input_strings, 88 input_strings=input_strings,
129 output_paths=[options.final_apk_path]) 89 output_paths=[options.final_apk_path])
130 90
131 91
92 def _NormalizeZip(path):
93 with tempfile.NamedTemporaryFile(suffix='.zip') as hermetic_signed_apk:
94 with zipfile.ZipFile(path, 'r') as zi:
95 with zipfile.ZipFile(hermetic_signed_apk, 'w') as zo:
96 for info in zi.infolist():
97 # Ignore 'extended local file headers'. Python doesn't write them
98 # properly (see https://bugs.python.org/issue1742205) which causes
99 # zipalign to miscalculate alignment. Since we don't use them except
100 # for alignment anyway, we write a stripped file here and let
101 # zipalign add them properly later. eLFHs are controlled by 'general
102 # purpose bit flag 03' (0x08) so we mask that out.
103 info.flag_bits = info.flag_bits & 0xF7
104
105 info.date_time = build_utils.HERMETIC_TIMESTAMP
106 zo.writestr(info, zi.read(info.filename))
107
108 shutil.copy(hermetic_signed_apk.name, path)
109
110
132 def FinalizeApk(options): 111 def FinalizeApk(options):
133 with tempfile.NamedTemporaryFile() as signed_apk_path_tmp, \ 112 with tempfile.NamedTemporaryFile() as signed_apk_path_tmp:
134 tempfile.NamedTemporaryFile() as apk_to_sign_tmp:
135
136 if options.load_library_from_zip:
137 # We alter the name of the library so that the Android Package Manager
138 # does not extract it into a separate file. This must be done before
139 # signing, as the filename is part of the signed manifest. At the same
140 # time we uncompress the library, which is necessary so that it can be
141 # loaded directly from the APK.
142 # Move the library to a page boundary by adding a page alignment file.
143 apk_to_sign = apk_to_sign_tmp.name
144 RenameInflateAndAddPageAlignment(
145 options.rezip_apk_jar_path, options.unsigned_apk_path, apk_to_sign)
146 else:
147 apk_to_sign = options.unsigned_apk_path
148
149 signed_apk_path = signed_apk_path_tmp.name 113 signed_apk_path = signed_apk_path_tmp.name
150 JarSigner(options.key_path, options.key_name, options.key_passwd, 114 JarSigner(options.key_path, options.key_name, options.key_passwd,
151 apk_to_sign, signed_apk_path) 115 options.unsigned_apk_path, signed_apk_path)
116 # Make the newly added signing files hermetic.
117 _NormalizeZip(signed_apk_path)
152 118
153 # Make the signing files hermetic. 119 AlignApk(options.zipalign_path, signed_apk_path, options.final_apk_path)
154 with tempfile.NamedTemporaryFile(suffix='.zip') as hermetic_signed_apk:
155 with zipfile.ZipFile(signed_apk_path, 'r') as zi:
156 with zipfile.ZipFile(hermetic_signed_apk, 'w') as zo:
157 for info in zi.infolist():
158 # Ignore 'extended local file headers'. Python doesn't write them
159 # properly (see https://bugs.python.org/issue1742205) which causes
160 # zipalign to miscalculate alignment. Since we don't use them except
161 # for alignment anyway, we write a stripped file here and let
162 # zipalign add them properly later. eLFHs are controlled by 'general
163 # purpose bit flag 03' (0x08) so we mask that out.
164 info.flag_bits = info.flag_bits & 0xF7
165
166 info.date_time = build_utils.HERMETIC_TIMESTAMP
167 zo.writestr(info, zi.read(info.filename))
168
169 shutil.copy(hermetic_signed_apk.name, signed_apk_path)
170
171 if options.load_library_from_zip:
172 # Reorder the contents of the APK. This re-establishes the canonical
173 # order which means the library will be back at its page aligned location.
174 # This step also aligns uncompressed items to 4 bytes.
175 ReorderAndAlignApk(
176 options.rezip_apk_jar_path, signed_apk_path, options.final_apk_path)
177 else:
178 # Align uncompressed items to 4 bytes
179 AlignApk(options.zipalign_path,
180 options.page_align_shared_libraries,
181 signed_apk_path,
182 options.final_apk_path)
183 120
184 121
185 if __name__ == '__main__': 122 if __name__ == '__main__':
186 sys.exit(main(sys.argv[1:])) 123 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « build/android/gyp/apkbuilder.py ('k') | build/android/rezip/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698