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