1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2023 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18import os 19import stat 20 21from services.interface.preload_interface import PreloadInterface 22from util.io_util import IoUtil 23from util.preloader.preloader_process_data import Dirs, Outputs, Product 24from util.preloader.parse_lite_subsystems_config import parse_lite_subsystem_config 25from util.log_util import LogUtil 26 27 28class OHOSPreloader(PreloadInterface): 29 30 def __init__(self): 31 super().__init__() 32 self._dirs = "" 33 self._outputs = "" 34 self._product = "" 35 self._os_level = "" 36 self._target_cpu = "" 37 self._target_os = "" 38 self._toolchain_label = "" 39 self._subsystem_info = {} 40 self._all_parts = {} 41 self._build_vars = {} 42 self._compile_standard_whitelist_info = {} 43 self._compile_env_allowlist_info = {} 44 self._hvigor_compile_whitelist_info = {} 45 46 def __post_init__(self): 47 self._dirs = Dirs(self._config) 48 self._outputs = Outputs(self._dirs.preloader_output_dir) 49 self._product = Product(self._dirs, self._config) 50 self._all_parts = self._product._parts 51 self._build_vars = self._product._build_vars 52 self._os_level = self._build_vars.get('os_level') 53 self._target_os = self._build_vars.get('target_os') 54 self._target_cpu = self._build_vars.get('target_cpu') 55 self._toolchain_label = self._build_vars.get('product_toolchain_label') 56 self._subsystem_info = self._get_org_subsystem_info() 57 self._compile_standard_whitelist_info = self._get_compile_standard_whitelist_info() 58 self._compile_env_allowlist_info = self._get_compile_env_allowlist_info() 59 self._hvigor_compile_whitelist_info = self._get_hvigor_compile_whitelist_info() 60 61# generate method 62 63 '''Description: generate platforms build info to "out/preloader/{product_name}/platforms.build" 64 @parameter:none 65 @return :none 66 ''' 67 68 def _generate_platforms_build(self): 69 config = { 70 'target_os': self._target_os, 71 "target_cpu": self._target_cpu, 72 "toolchain": self._toolchain_label, 73 "parts_config": os.path.relpath(self._outputs.parts_json, 74 self._dirs.preloader_output_dir) 75 } 76 platform_config = {'version': 2, 'platforms': {'phone': config}} 77 IoUtil.dump_json_file(self._outputs.platforms_build, platform_config) 78 LogUtil.hb_info( 79 'generated platforms build info to {}/platforms.build'.format( 80 self._dirs.preloader_output_dir), mode=self.config.log_mode) 81 82 '''Description: generate build gnargs prop info to "out/preloader/{product_name}/build_gnargs.prop" 83 @parameter:none 84 @return :none 85 ''' 86 87 def _generate_build_gnargs_prop(self): 88 all_features = {} 89 for _part_name, vals in self._all_parts.items(): 90 _features = vals.get('features') 91 if _features: 92 all_features.update(_features) 93 attr_list = [] 94 for key, val in all_features.items(): 95 _item = '' 96 if isinstance(val, bool): 97 _item = f'{key}={str(val).lower()}' 98 elif isinstance(val, int): 99 _item = f'{key}={val}' 100 elif isinstance(val, str): 101 _item = f'{key}="{val}"' 102 else: 103 raise Exception("part feature '{key}:{val}' type not support.") 104 attr_list.append(_item) 105 with os.fdopen(os.open(self._outputs.build_gnargs_prop, 106 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 107 fobj.write('\n'.join(attr_list)) 108 LogUtil.hb_info( 109 'generated build gnargs prop info to {}/build_gnargs.prop'.format( 110 self._dirs.preloader_output_dir), mode=self.config.log_mode) 111 112 '''Description: generate features to "out/preloader/{product_name}/features.json" 113 @parameter:none 114 @return :none 115 ''' 116 117 def _generate_features_json(self): 118 all_features = {} 119 part_feature_map = {} 120 for _part_name, vals in self._all_parts.items(): 121 _features = vals.get('features') 122 if _features: 123 all_features.update(_features) 124 if _features: 125 part_feature_map[_part_name.split( 126 ':')[1]] = list(_features.keys()) 127 parts_feature_info = { 128 "features": all_features, 129 "part_to_feature": part_feature_map 130 } 131 IoUtil.dump_json_file(self._outputs.features_json, parts_feature_info) 132 LogUtil.hb_info( 133 'generated features info to {}/features.json'.format( 134 self._dirs.preloader_output_dir), mode=self.config.log_mode) 135 136 '''Description: generate syscap to "out/preloader/product_name/syscap.json" 137 @parameter:none 138 @return :none 139 ''' 140 141 def _generate_syscap_json(self): 142 all_syscap = {} 143 part_syscap_map = {} 144 for _part_name, vals in self._all_parts.items(): 145 _syscap = vals.get('syscap') 146 if _syscap: 147 all_syscap.update(_syscap) 148 part_syscap_map[_part_name.split(':')[1]] = _syscap 149 parts_syscap_info = { 150 "syscap": all_syscap, 151 "part_to_syscap": part_syscap_map 152 } 153 IoUtil.dump_json_file(self._outputs.syscap_json, parts_syscap_info) 154 LogUtil.hb_info( 155 'generated syscap info to {}/syscap.json'.format( 156 self._dirs.preloader_output_dir), mode=self.config.log_mode) 157 158 '''Description: generate exclusion modules info to "out/preloader/product_name/exclusion_modules.json" 159 @parameter:none 160 @return :none 161 ''' 162 163 def _generate_exclusion_modules_json(self): 164 exclusions = {} 165 for _part_name, vals in self._all_parts.items(): 166 _exclusions = vals.get('exclusions') 167 if _exclusions: 168 pair = dict() 169 pair[_part_name] = _exclusions 170 exclusions.update(pair) 171 IoUtil.dump_json_file(self._outputs.exclusion_modules_json, exclusions) 172 LogUtil.hb_info( 173 'generated exclusion modules info to {}/exclusion_modules.json'.format( 174 self._dirs.preloader_output_dir), mode=self.config.log_mode) 175 176 '''Description: generate build config info to "out/preloader/product_name/build_config.json" 177 @parameter:none 178 @return :none 179 ''' 180 181 def _generate_build_config_json(self): 182 IoUtil.dump_json_file( 183 self._outputs.build_config_json, self._build_vars) 184 LogUtil.hb_info( 185 'generated build config info to {}/build_config.json'.format( 186 self._dirs.preloader_output_dir), mode=self.config.log_mode) 187 188 '''Description: generate build prop info to "out/preloader/product_name/build.prop" 189 @parameter:none 190 @return :none 191 ''' 192 193 def _generate_build_prop(self): 194 build_vars_list = [] 195 for key, value in self._build_vars.items(): 196 build_vars_list.append('{}={}'.format(key, value)) 197 with os.fdopen(os.open(self._outputs.build_prop, 198 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 199 fobj.write('\n'.join(build_vars_list)) 200 LogUtil.hb_info( 201 'generated build prop info to {}/build.prop'.format( 202 self._dirs.preloader_output_dir), mode=self.config.log_mode) 203 204 '''Description: generate parts to "out/preloader/product_name/parts.json" 205 @parameter:none 206 @return :none 207 ''' 208 209 def _generate_parts_json(self): 210 parts_info = {"parts": sorted(list(self._all_parts.keys()))} 211 IoUtil.dump_json_file(self._outputs.parts_json, parts_info) 212 LogUtil.hb_info( 213 'generated product parts info to {}/parts.json'.format( 214 self._dirs.preloader_output_dir), mode=self.config.log_mode) 215 216 '''Description: generate parts config to "out/preloader/product_name/parts_config.json" 217 @parameter:none 218 @return :none 219 ''' 220 221 def _generate_parts_config_json(self): 222 parts_config = {} 223 for part in self._all_parts: 224 part = part.replace(":", "_") 225 part = part.replace("-", "_") 226 part = part.replace(".", "_") 227 part = part.replace("/", "_") 228 parts_config[part] = True 229 IoUtil.dump_json_file(self._outputs.parts_config_json, parts_config) 230 LogUtil.hb_info( 231 'generated parts config info to {}/parts_config.json'.format( 232 self._dirs.preloader_output_dir), mode=self.config.log_mode) 233 234 '''Description: generate subsystem config info to "out/preloader/product_name/subsystem_config.json" 235 @parameter:none 236 @return :none 237 ''' 238 239 def _generate_subsystem_config_json(self): 240 if self._subsystem_info: 241 self._subsystem_info.update( 242 self._product._get_product_specific_subsystem()) 243 self._subsystem_info.update( 244 self._product._get_device_specific_subsystem()) 245 IoUtil.dump_json_file( 246 self._outputs.subsystem_config_json, self._subsystem_info) 247 LogUtil.hb_info( 248 'generated subsystem config info to {}/subsystem_config.json'.format( 249 self._dirs.preloader_output_dir), mode=self.config.log_mode) 250 251 '''Description: generate systemcapability_json to "out/preloader/product_name/systemcapability.json" 252 @parameter:none 253 @return :none 254 ''' 255 256 def _generate_systemcapability_json(self): 257 IoUtil.dump_json_file( 258 self._outputs.systemcapability_json, self._product._syscap_info) 259 LogUtil.hb_info( 260 'generated system capability info to {}/systemcapability.json'.format( 261 self._dirs.preloader_output_dir), mode=self.config.log_mode) 262 263 '''Description: generate compile_standard_whitelist info to "out/preloader/product_name/compile_standard_whitelist.json" 264 @parameter:none 265 @return :none 266 ''' 267 268 def _generate_compile_standard_whitelist_json(self): 269 IoUtil.dump_json_file( 270 self._outputs.compile_standard_whitelist_json, self._compile_standard_whitelist_info) 271 LogUtil.hb_info( 272 'generated compile_standard_whitelist info to {}/compile_standard_whitelist.json' 273 .format(self._dirs.preloader_output_dir), mode=self.config.log_mode) 274 275 def _generate_compile_env_allowlist_json(self): 276 IoUtil.dump_json_file( 277 self._outputs.compile_env_allowlist_json, self._compile_env_allowlist_info 278 ) 279 LogUtil.hb_info( 280 "generated compile_env_allowlist info to {}/compile_env_allowlist.json".format( 281 self._dirs.preloader_output_dir 282 ) 283 ) 284 285 def _generate_hvigor_compile_whitelist_json(self): 286 IoUtil.dump_json_file( 287 self._outputs.hvigor_compile_whitelist_json, self._hvigor_compile_whitelist_info 288 ) 289 LogUtil.hb_info( 290 "generated hvigor_compile_whitelist info to {}/hvigor_compile_hap_whitelist.json".format( 291 self._dirs.preloader_output_dir 292 ) 293 ) 294 295# get method 296 297 def _get_org_subsystem_info(self) -> dict: 298 subsystem_info = {} 299 if self._os_level == "standard": 300 subsystem_info = IoUtil.read_json_file( 301 self._dirs.subsystem_config_json) 302 elif self._os_level == "mini" or self._os_level == "small": 303 ohos_build_output_dir = os.path.join(self._dirs.preloader_output_dir, 304 '{}_system'.format(self._os_level)) 305 subsystem_info = parse_lite_subsystem_config( 306 self._dirs.lite_components_dir, ohos_build_output_dir, 307 self._dirs.source_root_dir, self._dirs.subsystem_config_json) 308 return subsystem_info 309 310 def _get_compile_standard_whitelist_info(self) -> dict: 311 allow_info_file = "out/products_ext/{}/compile_standard_whitelist.json".format(self.config.product) 312 allow_info_file = os.path.join(self._dirs.source_root_dir, allow_info_file) 313 if not os.path.exists(allow_info_file): 314 allow_info_file = os.path.join(self._dirs.source_root_dir, "build/compile_standard_whitelist.json") 315 316 allow_info = IoUtil.read_json_file(allow_info_file) 317 return allow_info 318 319 def _get_compile_env_allowlist_info(self) -> dict: 320 allow_env_file = os.path.join( 321 self._dirs.source_root_dir, 322 "out/products_ext/{}/compile_env_allowlist.json".format( 323 self.config.product 324 ), 325 ) 326 if not os.path.exists(allow_env_file): 327 allow_env_file = os.path.join( 328 self._dirs.source_root_dir, "build/compile_env_allowlist.json" 329 ) 330 331 if not os.path.exists(allow_env_file): 332 return {} 333 334 allow_env = IoUtil.read_json_file(allow_env_file) 335 return allow_env 336 337 def _get_hvigor_compile_whitelist_info(self) -> dict: 338 hvigor_compile_whitelist_file = os.path.join( 339 self._dirs.source_root_dir, 340 "out/products_ext/{}/hvigor_compile_hap_whitelist.json".format( 341 self.config.product 342 ), 343 ) 344 hvigor_compile_whitelist = dict() 345 if os.path.exists(hvigor_compile_whitelist_file): 346 hvigor_compile_whitelist = IoUtil.read_json_file(hvigor_compile_whitelist_file) 347 348 return hvigor_compile_whitelist 349