SzuWei Lin | 50e7f6c | 2018-01-02 15:26:58 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright 2017 - The Android Open Source Project |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. |
| 15 | """A utility to build and pack gsi_util.""" |
| 16 | |
| 17 | import argparse |
| 18 | from collections import namedtuple |
| 19 | import errno |
| 20 | import logging |
| 21 | import os |
| 22 | import shutil |
| 23 | import sys |
| 24 | import zipfile |
| 25 | |
| 26 | from gsi_util.utils.cmd_utils import run_command |
| 27 | |
| 28 | _MAKE_MODULE_NAME = 'gsi_util' |
| 29 | |
| 30 | RequiredItem = namedtuple('RequiredItem', 'dest src') |
| 31 | |
| 32 | # The list of dependency modules |
| 33 | # Format in (dest, src in host out) |
| 34 | REQUIRED_ITEMS = [ |
| 35 | # named as 'gsi_util.bin' to avoid conflict with the folder 'gsi_util' |
| 36 | RequiredItem('gsi_util.bin', 'bin/gsi_util'), |
| 37 | RequiredItem('bin/checkvintf', 'bin/checkvintf'), |
| 38 | RequiredItem('lib64/libbase.so', 'lib64/libbase.so'), |
| 39 | RequiredItem('lib64/liblog.so', 'lib64/liblog.so'), |
| 40 | RequiredItem('bin/simg2img', 'bin/simg2img'), |
| 41 | RequiredItem('lib64/libc++.so', 'lib64/libc++.so'), |
| 42 | ] # pyformat: disable |
| 43 | |
| 44 | # Files to be included to zip file additionally |
| 45 | INCLUDE_FILES = [ |
| 46 | 'README.md'] # pyformat: disable |
| 47 | |
| 48 | |
| 49 | def _check_android_env(): |
| 50 | if not os.environ.get('ANDROID_BUILD_TOP'): |
| 51 | raise EnvironmentError('Need \'lunch\'.') |
| 52 | |
| 53 | |
| 54 | def _switch_to_prog_dir(): |
| 55 | prog = sys.argv[0] |
| 56 | abspath = os.path.abspath(prog) |
| 57 | dirname = os.path.dirname(abspath) |
| 58 | os.chdir(dirname) |
| 59 | |
| 60 | |
| 61 | def _make_all(): |
| 62 | logging.info('Make %s...', _MAKE_MODULE_NAME) |
| 63 | |
| 64 | build_top = os.environ['ANDROID_BUILD_TOP'] |
| 65 | run_command(['make', '-j', _MAKE_MODULE_NAME], cwd=build_top) |
| 66 | |
| 67 | |
| 68 | def _create_dirs_and_copy_file(dest, src): |
| 69 | dir_path = os.path.dirname(dest) |
| 70 | try: |
| 71 | if dir_path != '': |
| 72 | os.makedirs(dir_path) |
| 73 | except OSError as exc: |
| 74 | if exc.errno != errno.EEXIST: |
| 75 | raise |
| 76 | logging.debug('copy(): %s %s', src, dest) |
| 77 | shutil.copy(src, dest) |
| 78 | |
| 79 | |
| 80 | def _copy_deps(): |
| 81 | logging.info('Copy depend files...') |
| 82 | host_out = os.environ['ANDROID_HOST_OUT'] |
| 83 | logging.debug(' ANDROID_HOST_OUT=%s', host_out) |
| 84 | |
| 85 | for item in REQUIRED_ITEMS: |
| 86 | print 'Copy {}...'.format(item.dest) |
| 87 | full_src = os.path.join(host_out, item.src) |
| 88 | _create_dirs_and_copy_file(item.dest, full_src) |
| 89 | |
| 90 | |
| 91 | def _build_zipfile(filename): |
| 92 | print 'Archive to {}...'.format(filename) |
| 93 | with zipfile.ZipFile(filename, mode='w') as zf: |
| 94 | for f in INCLUDE_FILES: |
| 95 | print 'Add {}'.format(f) |
| 96 | zf.write(f) |
| 97 | for f in REQUIRED_ITEMS: |
| 98 | print 'Add {}'.format(f[0]) |
| 99 | zf.write(f[0]) |
| 100 | |
| 101 | |
| 102 | def do_setup_env(args): |
| 103 | _check_android_env() |
| 104 | _make_all() |
| 105 | _switch_to_prog_dir() |
| 106 | _copy_deps() |
| 107 | |
| 108 | |
| 109 | def do_list_deps(args): |
| 110 | print 'Depend files (zip <== host out):' |
| 111 | for item in REQUIRED_ITEMS: |
| 112 | print ' {:20} <== {}'.format(item.dest, item.src) |
| 113 | print 'Other include files:' |
| 114 | for item in INCLUDE_FILES: |
| 115 | print ' {}'.format(item) |
| 116 | |
| 117 | |
| 118 | def do_build(args): |
| 119 | _check_android_env() |
| 120 | _make_all() |
| 121 | _switch_to_prog_dir() |
| 122 | _copy_deps() |
| 123 | _build_zipfile(args.output) |
| 124 | |
| 125 | |
| 126 | def main(argv): |
| 127 | |
| 128 | parser = argparse.ArgumentParser() |
| 129 | subparsers = parser.add_subparsers(title='COMMAND') |
| 130 | |
| 131 | # Command 'setup_env' |
| 132 | setup_env_parser = subparsers.add_parser( |
| 133 | 'setup_env', |
| 134 | help='setup environment by building and copying dependency files') |
| 135 | setup_env_parser.set_defaults(func=do_setup_env) |
| 136 | |
| 137 | # Command 'list_dep' |
| 138 | list_dep_parser = subparsers.add_parser( |
| 139 | 'list_deps', help='list all dependency files') |
| 140 | list_dep_parser.set_defaults(func=do_list_deps) |
| 141 | |
| 142 | # Command 'build' |
| 143 | # TODO(szuweilin@): do not add this command if this is runned by package |
| 144 | build_parser = subparsers.add_parser( |
| 145 | 'build', help='build a zip file including all required files') |
| 146 | build_parser.add_argument( |
| 147 | '-o', |
| 148 | '--output', |
| 149 | default='gsi_util.zip', |
| 150 | help='the name of output zip file (default: gsi_util.zip)') |
| 151 | build_parser.set_defaults(func=do_build) |
| 152 | |
| 153 | args = parser.parse_args(argv[1:]) |
| 154 | args.func(args) |
| 155 | |
| 156 | |
| 157 | if __name__ == '__main__': |
| 158 | main(sys.argv) |