1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021 Huawei Device Co., Ltd. 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 16import sys 17import argparse 18import os 19import shutil 20 21sys.path.append( 22 os.path.dirname(os.path.dirname(os.path.dirname( 23 os.path.abspath(__file__))))) 24from scripts.util.file_utils import read_json_file, write_json_file, write_file # noqa: E402 25from scripts.util import build_utils # noqa: E402 26 27 28def _get_modules_info(system_install_info: dict, depfiles: list): 29 modules_info_dict = {} 30 for subsystem_info in system_install_info: 31 part_name = subsystem_info.get('part_name') 32 part_info_file = subsystem_info.get('part_info_file') 33 34 # read subsystem module info 35 part_install_info = read_json_file(part_info_file) 36 if part_install_info is None: 37 raise Exception( 38 "read part '{}' installed modules info failed.".format( 39 part_name)) 40 depfiles.append(part_info_file) 41 42 for info in part_install_info: 43 module_def = info.get('module_def') 44 module_info_file = info.get('module_info_file') 45 depfiles.append(module_info_file) 46 if module_def not in modules_info_dict: 47 modules_info_dict[module_def] = module_info_file 48 return modules_info_dict 49 50 51def _get_post_process_modules_info(post_process_modules_info_files: list, depfiles: list): 52 modules_info_list = [] 53 for _modules_info_file in post_process_modules_info_files: 54 _modules_info = read_json_file(_modules_info_file) 55 if _modules_info is None: 56 raise Exception("read _modules_info_file '{}' failed.".format( 57 _modules_info_file)) 58 modules_info_list.extend(_modules_info) 59 depfiles.append(_modules_info_file) 60 return modules_info_list 61 62 63def copy_modules(system_install_info: dict, install_modules_info_file: str, 64 modules_info_file: str, module_list_file: str, 65 post_process_modules_info_files: list, platform_installed_path: str, 66 host_toolchain, additional_system_files: dict, depfiles: list): 67 output_result = [] 68 dest_list = [] 69 symlink_dest = [] 70 71 modules_info_dict = _get_modules_info(system_install_info, depfiles) 72 for value in modules_info_dict.values(): 73 module_info = read_json_file(value) 74 if not module_info: 75 raise Exception("read module install info file '{}' error.".format(value)) 76 install = module_info.get('install_enable') 77 if not install: 78 continue 79 output_result.append(module_info) 80 81 # get post process modules info 82 post_process_modules = _get_post_process_modules_info( 83 post_process_modules_info_files, depfiles) 84 for _module_info in post_process_modules: 85 install = _module_info.get('install_enable') 86 if not install: 87 continue 88 output_result.append(_module_info) 89 90 for source, system_path in additional_system_files: 91 shutil.copy(source, os.path.join(platform_installed_path, system_path)) 92 93 # copy modules 94 for module_info in output_result: 95 if module_info.get('type') == 'none': 96 continue 97 # copy module lib 98 label = module_info.get('label') 99 if label and host_toolchain in label: 100 continue 101 source = module_info.get('source') 102 dests = module_info.get('dest') 103 # check source 104 if not os.path.exists(source): 105 raise Exception("source '{}' doesn't exist.".format(source)) 106 depfiles.append(source) 107 for dest in dests: 108 if dest.startswith('/'): 109 dest = dest[1:] 110 dest_list.append(dest) 111 # dest_dir_prefix 112 if os.path.isfile(source): 113 dest_dir = os.path.join(platform_installed_path, 114 os.path.dirname(dest)) 115 elif os.path.isdir(source): 116 dest_dir = os.path.join(platform_installed_path, dest) 117 if not os.path.exists(dest_dir): 118 os.makedirs(dest_dir, exist_ok=True) 119 if os.path.isdir(source): 120 is_hvigor_hap = False 121 for filename in os.listdir(source): 122 if filename.endswith('.hap') or filename.endswith('.hsp'): 123 is_hvigor_hap = True 124 shutil.copy2(os.path.join(source, filename), 125 os.path.join(platform_installed_path, dest, filename)) 126 if not is_hvigor_hap: 127 shutil.copytree(source, os.path.join(platform_installed_path, dest), dirs_exist_ok=True) 128 else: 129 shutil.copy2(source, os.path.join(platform_installed_path, dest)) 130 131 # add symlink 132 if 'symlink' in module_info: 133 symlink_dest = module_info.get('symlink') 134 for dest in dests: 135 symlink_src_file = os.path.basename(dest) 136 for name in symlink_dest: 137 symlink_dest_dir = os.path.dirname(dest) 138 symlink_dest_file = os.path.join(platform_installed_path, 139 symlink_dest_dir, name) 140 if not os.path.exists(symlink_dest_file): 141 os.symlink(symlink_src_file, symlink_dest_file) 142 143 # write install module info to file 144 write_json_file(install_modules_info_file, modules_info_dict) 145 146 # write all module info 147 write_json_file(modules_info_file, output_result) 148 149 # output module list to file 150 write_file(module_list_file, '\n'.join(dest_list)) 151 152 153def main(): 154 parser = argparse.ArgumentParser() 155 parser.add_argument('--system-install-info-file', required=True) 156 parser.add_argument('--install-modules-info-file', required=True) 157 parser.add_argument('--modules-info-file', required=True) 158 parser.add_argument('--modules-list-file', required=True) 159 parser.add_argument('--platform-installed-path', required=True) 160 parser.add_argument('--system-dir', required=True) 161 parser.add_argument('--sa-profile-extract-dir', required=True) 162 parser.add_argument('--merged-sa-profile', required=True) 163 parser.add_argument('--depfile', required=True) 164 parser.add_argument('--system-image-zipfile', required=True) 165 parser.add_argument('--host-toolchain', required=True) 166 parser.add_argument( 167 '--additional-system-files', 168 action='append', 169 help="additional system files is used for files don't have module infos. \ 170 use with caution" 171 ) 172 parser.add_argument('--post-process-modules-info-files', 173 nargs='*', 174 default=[]) 175 args = parser.parse_args() 176 177 additional_system_files = [] 178 for tuple in args.additional_system_files or []: 179 filepath, system_path = tuple.split(':') 180 additional_system_files.append((filepath, system_path)) 181 182 depfiles = [] 183 build_utils.extract_all(args.merged_sa_profile, 184 args.sa_profile_extract_dir, 185 no_clobber=False) 186 sa_files = build_utils.get_all_files(args.sa_profile_extract_dir) 187 188 system_install_info = read_json_file(args.system_install_info_file) 189 if system_install_info is None: 190 raise Exception("read file '{}' failed.".format( 191 args.system_install_info_file)) 192 193 system_install_base_dir = args.system_dir 194 if os.path.exists(system_install_base_dir): 195 shutil.rmtree(system_install_base_dir) 196 print('remove system dir...') 197 os.makedirs(system_install_base_dir, exist_ok=True) 198 199 vendor_install_base_dir = os.path.join(args.platform_installed_path, 200 'vendor') 201 if os.path.exists(vendor_install_base_dir): 202 shutil.rmtree(vendor_install_base_dir) 203 print('remove vendor dir...') 204 205 eng_system_install_base_dir = os.path.join(args.platform_installed_path, 206 'eng_system') 207 if os.path.exists(eng_system_install_base_dir): 208 shutil.rmtree(eng_system_install_base_dir) 209 print('remove eng_system dir...') 210 211 eng_chipset_install_base_dir = os.path.join(args.platform_installed_path, 212 'eng_chipset') 213 if os.path.exists(eng_chipset_install_base_dir): 214 shutil.rmtree(eng_chipset_install_base_dir) 215 print('remove eng_chipset dir...') 216 217 sys_prod_install_base_dir = os.path.join(args.platform_installed_path, 218 'sys_prod') 219 if os.path.exists(sys_prod_install_base_dir): 220 shutil.rmtree(sys_prod_install_base_dir) 221 print('remove sys_prod dir...') 222 223 chip_prod_install_base_dir = os.path.join(args.platform_installed_path, 224 'chip_prod') 225 if os.path.exists(chip_prod_install_base_dir): 226 shutil.rmtree(chip_prod_install_base_dir) 227 print('remove chip_prod dir...') 228 229 updater_install_base_dir = os.path.join(args.platform_installed_path, 230 'updater') 231 if os.path.exists(updater_install_base_dir): 232 shutil.rmtree(updater_install_base_dir) 233 print('remove updater dir...') 234 235 updater_vendor_install_base_dir = os.path.join(args.platform_installed_path, 236 'updater_vendor') 237 if os.path.exists(updater_vendor_install_base_dir): 238 shutil.rmtree(updater_vendor_install_base_dir) 239 print('remove updater dir...') 240 241 ramdisk_install_base_dir = os.path.join(args.platform_installed_path, 242 'ramdisk') 243 if os.path.exists(ramdisk_install_base_dir): 244 shutil.rmtree(ramdisk_install_base_dir) 245 print('remove ramdisk dir...') 246 247 print('copy modules...') 248 copy_modules(system_install_info, args.install_modules_info_file, 249 args.modules_info_file, args.modules_list_file, 250 args.post_process_modules_info_files, 251 args.platform_installed_path, args.host_toolchain, 252 additional_system_files, depfiles) 253 254 if os.path.exists(args.system_image_zipfile): 255 os.unlink(args.system_image_zipfile) 256 build_utils.zip_dir(args.system_image_zipfile, args.system_dir) 257 depfiles.extend([item for item in depfiles if item not in sa_files]) 258 build_utils.write_depfile(args.depfile, args.install_modules_info_file, 259 depfiles) 260 return 0 261 262 263if __name__ == '__main__': 264 sys.exit(main()) 265