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