OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 """Adds the code parts to a resource APK.""" |
| 8 |
| 9 import argparse |
| 10 import os |
| 11 import shutil |
| 12 import sys |
| 13 import zipfile |
| 14 |
| 15 from util import build_utils |
| 16 |
| 17 |
| 18 def _ParseArgs(args): |
| 19 parser = argparse.ArgumentParser() |
| 20 build_utils.AddDepfileOption(parser) |
| 21 parser.add_argument('--resource-apk', |
| 22 help='An .ap_ file built using aapt', |
| 23 required=True) |
| 24 parser.add_argument('--output-apk', |
| 25 help='Path to the output file', |
| 26 required=True) |
| 27 parser.add_argument('--dex-file', |
| 28 help='Path to the classes.dex to use') |
| 29 # TODO(agrieve): Switch this to be a list of files rather than a directory. |
| 30 parser.add_argument('--native-libs-dir', |
| 31 help='Directory containing native libraries to include', |
| 32 default=[]) |
| 33 parser.add_argument('--android-abi', |
| 34 help='Android architecture to use for native libraries') |
| 35 options = parser.parse_args(args) |
| 36 if options.native_libs_dir and not options.android_abi: |
| 37 raise Exception('Must specify --android-abi with --native-libs-dir') |
| 38 return options |
| 39 |
| 40 |
| 41 def _ListSubPaths(path): |
| 42 """Returns a list of full paths to all files in the given path.""" |
| 43 return [os.path.join(path, name) for name in os.listdir(path)] |
| 44 |
| 45 |
| 46 def main(args): |
| 47 args = build_utils.ExpandFileArgs(args) |
| 48 options = _ParseArgs(args) |
| 49 |
| 50 native_libs = [] |
| 51 if options.native_libs_dir: |
| 52 native_libs = _ListSubPaths(options.native_libs_dir) |
| 53 |
| 54 input_paths = [options.resource_apk] + native_libs |
| 55 if options.dex_file: |
| 56 input_paths.append(options.dex_file) |
| 57 |
| 58 def on_stale_md5(): |
| 59 tmp_apk = options.output_apk + '.tmp' |
| 60 try: |
| 61 # Use a temp file to avoid creating an output if anything goes wrong. |
| 62 shutil.copyfile(options.resource_apk, tmp_apk) |
| 63 |
| 64 # TODO(agrieve): It would be more efficient to combine this step |
| 65 # with finalize_apk(), which sometimes aligns and uncompresses the |
| 66 # native libraries. |
| 67 with zipfile.ZipFile(tmp_apk, 'a', zipfile.ZIP_DEFLATED) as apk: |
| 68 for path in native_libs: |
| 69 basename = os.path.basename(path) |
| 70 apk.write(path, 'lib/%s/%s' % (options.android_abi, basename)) |
| 71 if options.dex_file: |
| 72 apk.write(options.dex_file, 'classes.dex') |
| 73 |
| 74 shutil.move(tmp_apk, options.output_apk) |
| 75 finally: |
| 76 if os.path.exists(tmp_apk): |
| 77 os.unlink(tmp_apk) |
| 78 |
| 79 build_utils.CallAndWriteDepfileIfStale( |
| 80 on_stale_md5, |
| 81 options, |
| 82 input_paths=input_paths, |
| 83 output_paths=[options.output_apk]) |
| 84 |
| 85 |
| 86 if __name__ == '__main__': |
| 87 main(sys.argv[1:]) |
OLD | NEW |