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 17import argparse 18from collections import namedtuple 19import errno 20import logging 21import os 22import shutil 23import sys 24import zipfile 25 26from gsi_util.utils.cmd_utils import run_command 27 28_MAKE_MODULE_NAME = 'gsi_util' 29 30RequiredItem = namedtuple('RequiredItem', 'dest src') 31 32# The list of dependency modules 33# Format in (dest, src in host out) 34REQUIRED_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 45INCLUDE_FILES = [ 46 'README.md'] # pyformat: disable 47 48 49def _check_android_env(): 50 if not os.environ.get('ANDROID_BUILD_TOP'): 51 raise EnvironmentError('Need \'lunch\'.') 52 53 54def _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 61def _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 68def _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 80def _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 91def _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 102def do_setup_env(args): 103 _check_android_env() 104 _make_all() 105 _switch_to_prog_dir() 106 _copy_deps() 107 108 109def 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 118def 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 126def 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 157if __name__ == '__main__': 158 main(sys.argv) 159