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/secilc', 'bin/secilc'), 41 RequiredItem('lib64/libsepol.so', 'lib64/libsepol.so'), 42 RequiredItem('bin/simg2img', 'bin/simg2img'), 43 RequiredItem('lib64/libc++.so', 'lib64/libc++.so'), 44] # pyformat: disable 45 46# Files to be included to zip file additionally 47INCLUDE_FILES = [ 48 'README.md'] # pyformat: disable 49 50 51def _check_android_env(): 52 if not os.environ.get('ANDROID_BUILD_TOP'): 53 raise EnvironmentError('Need \'lunch\'.') 54 55 56def _switch_to_prog_dir(): 57 prog = sys.argv[0] 58 abspath = os.path.abspath(prog) 59 dirname = os.path.dirname(abspath) 60 os.chdir(dirname) 61 62 63def _make_all(): 64 logging.info('Make %s...', _MAKE_MODULE_NAME) 65 66 build_top = os.environ['ANDROID_BUILD_TOP'] 67 run_command(['make', '-j', _MAKE_MODULE_NAME], cwd=build_top) 68 69 70def _create_dirs_and_copy_file(dest, src): 71 dir_path = os.path.dirname(dest) 72 try: 73 if dir_path != '': 74 os.makedirs(dir_path) 75 except OSError as exc: 76 if exc.errno != errno.EEXIST: 77 raise 78 logging.debug('copy(): %s %s', src, dest) 79 shutil.copy(src, dest) 80 81 82def _copy_deps(): 83 logging.info('Copy depend files...') 84 host_out = os.environ['ANDROID_HOST_OUT'] 85 logging.debug(' ANDROID_HOST_OUT=%s', host_out) 86 87 for item in REQUIRED_ITEMS: 88 print 'Copy {}...'.format(item.dest) 89 full_src = os.path.join(host_out, item.src) 90 _create_dirs_and_copy_file(item.dest, full_src) 91 92 93def _build_zipfile(filename): 94 print 'Archive to {}...'.format(filename) 95 with zipfile.ZipFile(filename, mode='w') as zf: 96 for f in INCLUDE_FILES: 97 print 'Add {}'.format(f) 98 zf.write(f) 99 for f in REQUIRED_ITEMS: 100 print 'Add {}'.format(f[0]) 101 zf.write(f[0]) 102 103 104def do_setup_env(args): 105 _check_android_env() 106 _make_all() 107 _switch_to_prog_dir() 108 _copy_deps() 109 110 111def do_list_deps(args): 112 print 'Depend files (zip <== host out):' 113 for item in REQUIRED_ITEMS: 114 print ' {:20} <== {}'.format(item.dest, item.src) 115 print 'Other include files:' 116 for item in INCLUDE_FILES: 117 print ' {}'.format(item) 118 119 120def do_build(args): 121 _check_android_env() 122 _make_all() 123 _switch_to_prog_dir() 124 _copy_deps() 125 _build_zipfile(args.output) 126 127 128def main(argv): 129 130 parser = argparse.ArgumentParser() 131 subparsers = parser.add_subparsers(title='COMMAND') 132 133 # Command 'setup_env' 134 setup_env_parser = subparsers.add_parser( 135 'setup_env', 136 help='setup environment by building and copying dependency files') 137 setup_env_parser.set_defaults(func=do_setup_env) 138 139 # Command 'list_dep' 140 list_dep_parser = subparsers.add_parser( 141 'list_deps', help='list all dependency files') 142 list_dep_parser.set_defaults(func=do_list_deps) 143 144 # Command 'build' 145 # TODO(szuweilin@): do not add this command if this is runned by package 146 build_parser = subparsers.add_parser( 147 'build', help='build a zip file including all required files') 148 build_parser.add_argument( 149 '-o', 150 '--output', 151 default='gsi_util.zip', 152 help='the name of output zip file (default: gsi_util.zip)') 153 build_parser.set_defaults(func=do_build) 154 155 args = parser.parse_args(argv[1:]) 156 args.func(args) 157 158 159if __name__ == '__main__': 160 main(sys.argv) 161