OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ Merges a 64-bit and a 32-bit APK into a single APK | 6 """ Merges a 64-bit and a 32-bit APK into a single APK |
7 | 7 |
8 """ | 8 """ |
9 | 9 |
10 import os | 10 import os |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 114 |
115 def RemoveMetafiles(tmp_apk): | 115 def RemoveMetafiles(tmp_apk): |
116 """ Remove all meta info to avoid certificate clashes """ | 116 """ Remove all meta info to avoid certificate clashes """ |
117 try: | 117 try: |
118 build_utils.CheckOutput(['zip', '-d', tmp_apk, 'META-INF/*']) | 118 build_utils.CheckOutput(['zip', '-d', tmp_apk, 'META-INF/*']) |
119 except build_utils.CalledProcessError as e: | 119 except build_utils.CalledProcessError as e: |
120 raise ApkMergeFailure('Failed to delete Meta folder: ' + e.output) | 120 raise ApkMergeFailure('Failed to delete Meta folder: ' + e.output) |
121 | 121 |
122 | 122 |
123 def SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, zipalign_path, | 123 def SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, zipalign_path, |
124 keystore_path, key_name, key_password): | 124 keystore_path, key_name, key_password, |
| 125 page_align_shared_libraries): |
125 try: | 126 try: |
126 finalize_apk.JarSigner( | 127 finalize_apk.JarSigner( |
127 keystore_path, | 128 keystore_path, |
128 key_name, | 129 key_name, |
129 key_password, | 130 key_password, |
130 tmp_apk, | 131 tmp_apk, |
131 signed_tmp_apk) | 132 signed_tmp_apk) |
132 except build_utils.CalledProcessError as e: | 133 except build_utils.CalledProcessError as e: |
133 raise ApkMergeFailure('Failed to sign APK: ' + e.output) | 134 raise ApkMergeFailure('Failed to sign APK: ' + e.output) |
134 | 135 |
135 try: | 136 try: |
136 finalize_apk.AlignApk(zipalign_path, signed_tmp_apk, new_apk) | 137 finalize_apk.AlignApk(zipalign_path, |
| 138 page_align_shared_libraries, |
| 139 signed_tmp_apk, |
| 140 new_apk) |
137 except build_utils.CalledProcessError as e: | 141 except build_utils.CalledProcessError as e: |
138 raise ApkMergeFailure('Failed to align APK: ' + e.output) | 142 raise ApkMergeFailure('Failed to align APK: ' + e.output) |
139 | 143 |
140 | 144 |
141 def main(): | 145 def main(): |
142 parser = argparse.ArgumentParser( | 146 parser = argparse.ArgumentParser( |
143 description='Merge a 32-bit APK into a 64-bit APK') | 147 description='Merge a 32-bit APK into a 64-bit APK') |
144 # Using type=os.path.abspath converts file paths to absolute paths so that | 148 # Using type=os.path.abspath converts file paths to absolute paths so that |
145 # we can change working directory without affecting these paths | 149 # we can change working directory without affecting these paths |
146 parser.add_argument('--apk_32bit', required=True, type=os.path.abspath) | 150 parser.add_argument('--apk_32bit', required=True, type=os.path.abspath) |
147 parser.add_argument('--apk_64bit', required=True, type=os.path.abspath) | 151 parser.add_argument('--apk_64bit', required=True, type=os.path.abspath) |
148 parser.add_argument('--out_apk', required=True, type=os.path.abspath) | 152 parser.add_argument('--out_apk', required=True, type=os.path.abspath) |
149 parser.add_argument('--zipalign_path', required=True, type=os.path.abspath) | 153 parser.add_argument('--zipalign_path', required=True, type=os.path.abspath) |
150 parser.add_argument('--keystore_path', required=True, type=os.path.abspath) | 154 parser.add_argument('--keystore_path', required=True, type=os.path.abspath) |
151 parser.add_argument('--key_name', required=True) | 155 parser.add_argument('--key_name', required=True) |
152 parser.add_argument('--key_password', required=True) | 156 parser.add_argument('--key_password', required=True) |
153 parser.add_argument('--shared_library', required=True) | 157 parser.add_argument('--shared_library', required=True) |
| 158 parser.add_argument('--page-align-shared-libraries', action='store_true') |
| 159 parser.add_argument('--uncompress-shared-libraries', action='store_true') |
154 args = parser.parse_args() | 160 args = parser.parse_args() |
155 | 161 |
156 tmp_dir = tempfile.mkdtemp() | 162 tmp_dir = tempfile.mkdtemp() |
157 tmp_dir_64 = os.path.join(tmp_dir, '64_bit') | 163 tmp_dir_64 = os.path.join(tmp_dir, '64_bit') |
158 tmp_dir_32 = os.path.join(tmp_dir, '32_bit') | 164 tmp_dir_32 = os.path.join(tmp_dir, '32_bit') |
159 tmp_apk = os.path.join(tmp_dir, 'tmp.apk') | 165 tmp_apk = os.path.join(tmp_dir, 'tmp.apk') |
160 signed_tmp_apk = os.path.join(tmp_dir, 'signed.apk') | 166 signed_tmp_apk = os.path.join(tmp_dir, 'signed.apk') |
161 new_apk = args.out_apk | 167 new_apk = args.out_apk |
162 | 168 |
163 # Expected files to copy from 32- to 64-bit APK together with an extra flag | 169 # Expected files to copy from 32- to 64-bit APK together with an extra flag |
164 # setting the compression level of the file | 170 # setting the compression level of the file |
165 expected_files = {'snapshot_blob_32.bin': ['-0'], | 171 expected_files = {'snapshot_blob_32.bin': ['-0'], |
166 'natives_blob_32.bin': ['-0'], | 172 'natives_blob_32.bin': ['-0'], |
167 args.shared_library: []} | 173 args.shared_library: []} |
168 | 174 |
| 175 if args.uncompress_shared_libraries: |
| 176 expected_files[args.shared_library] += ['-0'] |
| 177 |
169 try: | 178 try: |
170 shutil.copyfile(args.apk_64bit, tmp_apk) | 179 shutil.copyfile(args.apk_64bit, tmp_apk) |
171 | 180 |
172 # need to unpack APKs to compare their contents | 181 # need to unpack APKs to compare their contents |
173 UnpackApk(args.apk_64bit, tmp_dir_64) | 182 UnpackApk(args.apk_64bit, tmp_dir_64) |
174 UnpackApk(args.apk_32bit, tmp_dir_32) | 183 UnpackApk(args.apk_32bit, tmp_dir_32) |
175 | 184 |
176 # TODO(sgurun) remove WebViewPlatformBridge.apk from this list crbug/580678 | 185 # TODO(sgurun) remove WebViewPlatformBridge.apk from this list crbug/580678 |
177 dcmp = filecmp.dircmp( | 186 dcmp = filecmp.dircmp( |
178 tmp_dir_64, | 187 tmp_dir_64, |
179 tmp_dir_32, | 188 tmp_dir_32, |
180 ignore=['META-INF', 'AndroidManifest.xml', 'WebViewPlatformBridge.apk']) | 189 ignore=['META-INF', 'AndroidManifest.xml', 'WebViewPlatformBridge.apk']) |
181 | 190 |
182 diff_files = GetDiffFiles(dcmp, tmp_dir_32) | 191 diff_files = GetDiffFiles(dcmp, tmp_dir_32) |
183 | 192 |
184 # Check that diff_files match exactly those files we want to insert into | 193 # Check that diff_files match exactly those files we want to insert into |
185 # the 64-bit APK. | 194 # the 64-bit APK. |
186 CheckFilesExpected(diff_files, expected_files) | 195 CheckFilesExpected(diff_files, expected_files) |
187 | 196 |
188 RemoveMetafiles(tmp_apk) | 197 RemoveMetafiles(tmp_apk) |
189 | 198 |
190 AddDiffFiles(diff_files, tmp_dir_32, tmp_apk, expected_files) | 199 AddDiffFiles(diff_files, tmp_dir_32, tmp_apk, expected_files) |
191 | 200 |
192 SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, args.zipalign_path, | 201 SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, args.zipalign_path, |
193 args.keystore_path, args.key_name, args.key_password) | 202 args.keystore_path, args.key_name, args.key_password, |
| 203 args.page_align_shared_libraries) |
194 | 204 |
195 except ApkMergeFailure as e: | 205 except ApkMergeFailure as e: |
196 print e | 206 print e |
197 return 1 | 207 return 1 |
198 finally: | 208 finally: |
199 shutil.rmtree(tmp_dir) | 209 shutil.rmtree(tmp_dir) |
200 return 0 | 210 return 0 |
201 | 211 |
202 | 212 |
203 if __name__ == '__main__': | 213 if __name__ == '__main__': |
204 sys.exit(main()) | 214 sys.exit(main()) |
OLD | NEW |