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 45 def __post_init__(self): 46 self._dirs = Dirs(self._config) 47 self._outputs = Outputs(self._dirs.preloader_output_dir) 48 self._product = Product(self._dirs, self._config) 49 self._all_parts = self._product._parts 50 self._build_vars = self._product._build_vars 51 self._os_level = self._build_vars.get('os_level') 52 self._target_os = self._build_vars.get('target_os') 53 self._target_cpu = self._build_vars.get('target_cpu') 54 self._toolchain_label = self._build_vars.get('product_toolchain_label') 55 self._subsystem_info = self._get_org_subsystem_info() 56 self._compile_standard_whitelist_info = self._get_compile_standard_whitelist_info() 57 self._compile_env_allowlist_info = self._get_compile_env_allowlist_info() 58 59# generate method 60 61 '''Description: generate platforms build info to "out/preloader/{product_name}/platforms.build" 62 @parameter:none 63 @return :none 64 ''' 65 66 def _generate_platforms_build(self): 67 config = { 68 'target_os': self._target_os, 69 "target_cpu": self._target_cpu, 70 "toolchain": self._toolchain_label, 71 "parts_config": os.path.relpath(self._outputs.parts_json, 72 self._dirs.preloader_output_dir) 73 } 74 platform_config = {'version': 2, 'platforms': {'phone': config}} 75 IoUtil.dump_json_file(self._outputs.platforms_build, platform_config) 76 LogUtil.hb_info( 77 'generated platforms build info to {}/platforms.build'.format( 78 self._dirs.preloader_output_dir), mode=self.config.log_mode) 79 80 '''Description: generate build gnargs prop info to "out/preloader/{product_name}/build_gnargs.prop" 81 @parameter:none 82 @return :none 83 ''' 84 85 def _generate_build_gnargs_prop(self): 86 all_features = {} 87 for _part_name, vals in self._all_parts.items(): 88 _features = vals.get('features') 89 if _features: 90 all_features.update(_features) 91 attr_list = [] 92 for key, val in all_features.items(): 93 _item = '' 94 if isinstance(val, bool): 95 _item = f'{key}={str(val).lower()}' 96 elif isinstance(val, int): 97 _item = f'{key}={val}' 98 elif isinstance(val, str): 99 _item = f'{key}="{val}"' 100 else: 101 raise Exception("part feature '{key}:{val}' type not support.") 102 attr_list.append(_item) 103 with os.fdopen(os.open(self._outputs.build_gnargs_prop, 104 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 105 fobj.write('\n'.join(attr_list)) 106 LogUtil.hb_info( 107 'generated build gnargs prop info to {}/build_gnargs.prop'.format( 108 self._dirs.preloader_output_dir), mode=self.config.log_mode) 109 110 '''Description: generate features to "out/preloader/{product_name}/features.json" 111 @parameter:none 112 @return :none 113 ''' 114 115 def _generate_features_json(self): 116 all_features = {} 117 part_feature_map = {} 118 for _part_name, vals in self._all_parts.items(): 119 _features = vals.get('features') 120 if _features: 121 all_features.update(_features) 122 if _features: 123 part_feature_map[_part_name.split( 124 ':')[1]] = list(_features.keys()) 125 parts_feature_info = { 126 "features": all_features, 127 "part_to_feature": part_feature_map 128 } 129 IoUtil.dump_json_file(self._outputs.features_json, parts_feature_info) 130 LogUtil.hb_info( 131 'generated features info to {}/features.json'.format( 132 self._dirs.preloader_output_dir), mode=self.config.log_mode) 133 134 '''Description: generate syscap to "out/preloader/product_name/syscap.json" 135 @parameter:none 136 @return :none 137 ''' 138 139 def _generate_syscap_json(self): 140 all_syscap = {} 141 part_syscap_map = {} 142 for _part_name, vals in self._all_parts.items(): 143 _syscap = vals.get('syscap') 144 if _syscap: 145 all_syscap.update(_syscap) 146 part_syscap_map[_part_name.split(':')[1]] = _syscap 147 parts_syscap_info = { 148 "syscap": all_syscap, 149 "part_to_syscap": part_syscap_map 150 } 151 IoUtil.dump_json_file(self._outputs.syscap_json, parts_syscap_info) 152 LogUtil.hb_info( 153 'generated syscap info to {}/syscap.json'.format( 154 self._dirs.preloader_output_dir), mode=self.config.log_mode) 155 156 '''Description: generate exclusion modules info to "out/preloader/product_name/exclusion_modules.json" 157 @parameter:none 158 @return :none 159 ''' 160 161 def _generate_exclusion_modules_json(self): 162 exclusions = {} 163 for _part_name, vals in self._all_parts.items(): 164 _exclusions = vals.get('exclusions') 165 if _exclusions: 166 pair = dict() 167 pair[_part_name] = _exclusions 168 exclusions.update(pair) 169 IoUtil.dump_json_file(self._outputs.exclusion_modules_json, exclusions) 170 LogUtil.hb_info( 171 'generated exclusion modules info to {}/exclusion_modules.json'.format( 172 self._dirs.preloader_output_dir), mode=self.config.log_mode) 173 174 '''Description: generate build config info to "out/preloader/product_name/build_config.json" 175 @parameter:none 176 @return :none 177 ''' 178 179 def _generate_build_config_json(self): 180 IoUtil.dump_json_file( 181 self._outputs.build_config_json, self._build_vars) 182 LogUtil.hb_info( 183 'generated build config info to {}/build_config.json'.format( 184 self._dirs.preloader_output_dir), mode=self.config.log_mode) 185 186 '''Description: generate build prop info to "out/preloader/product_name/build.prop" 187 @parameter:none 188 @return :none 189 ''' 190 191 def _generate_build_prop(self): 192 build_vars_list = [] 193 for key, value in self._build_vars.items(): 194 build_vars_list.append('{}={}'.format(key, value)) 195 with os.fdopen(os.open(self._outputs.build_prop, 196 os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 197 fobj.write('\n'.join(build_vars_list)) 198 LogUtil.hb_info( 199 'generated build prop info to {}/build.prop'.format( 200 self._dirs.preloader_output_dir), mode=self.config.log_mode) 201 202 '''Description: generate parts to "out/preloader/product_name/parts.json" 203 @parameter:none 204 @return :none 205 ''' 206 207 def _generate_parts_json(self): 208 parts_info = {"parts": sorted(list(self._all_parts.keys()))} 209 IoUtil.dump_json_file(self._outputs.parts_json, parts_info) 210 LogUtil.hb_info( 211 'generated product parts info to {}/parts.json'.format( 212 self._dirs.preloader_output_dir), mode=self.config.log_mode) 213 214 '''Description: generate parts config to "out/preloader/product_name/parts_config.json" 215 @parameter:none 216 @return :none 217 ''' 218 219 def _generate_parts_config_json(self): 220 parts_config = {} 221 for part in self._all_parts: 222 part = part.replace(":", "_") 223 part = part.replace("-", "_") 224 part = part.replace(".", "_") 225 part = part.replace("/", "_") 226 parts_config[part] = True 227 IoUtil.dump_json_file(self._outputs.parts_config_json, parts_config) 228 LogUtil.hb_info( 229 'generated parts config info to {}/parts_config.json'.format( 230 self._dirs.preloader_output_dir), mode=self.config.log_mode) 231 232 '''Description: generate subsystem config info to "out/preloader/product_name/subsystem_config.json" 233 @parameter:none 234 @return :none 235 ''' 236 237 def _generate_subsystem_config_json(self): 238 if self._subsystem_info: 239 self._subsystem_info.update( 240 self._product._get_product_specific_subsystem()) 241 self._subsystem_info.update( 242 self._product._get_device_specific_subsystem()) 243 IoUtil.dump_json_file( 244 self._outputs.subsystem_config_json, self._subsystem_info) 245 LogUtil.hb_info( 246 'generated subsystem config info to {}/subsystem_config.json'.format( 247 self._dirs.preloader_output_dir), mode=self.config.log_mode) 248 249 '''Description: generate systemcapability_json to "out/preloader/product_name/systemcapability.json" 250 @parameter:none 251 @return :none 252 ''' 253 254 def _generate_systemcapability_json(self): 255 IoUtil.dump_json_file( 256 self._outputs.systemcapability_json, self._product._syscap_info) 257 LogUtil.hb_info( 258 'generated system capability info to {}/systemcapability.json'.format( 259 self._dirs.preloader_output_dir), mode=self.config.log_mode) 260 261 '''Description: generate compile_standard_whitelist info to "out/preloader/product_name/compile_standard_whitelist.json" 262 @parameter:none 263 @return :none 264 ''' 265 266 def _generate_compile_standard_whitelist_json(self): 267 IoUtil.dump_json_file( 268 self._outputs.compile_standard_whitelist_json, self._compile_standard_whitelist_info) 269 LogUtil.hb_info( 270 'generated compile_standard_whitelist info to {}/compile_standard_whitelist.json' 271 .format(self._dirs.preloader_output_dir), mode=self.config.log_mode) 272 273 def _generate_compile_env_allowlist_json(self): 274 IoUtil.dump_json_file( 275 self._outputs.compile_env_allowlist_json, self._compile_env_allowlist_info 276 ) 277 LogUtil.hb_info( 278 "generated compile_env_allowlist info to {}/compile_env_allowlist.json".format( 279 self._dirs.preloader_output_dir 280 ) 281 ) 282 283# get method 284 285 def _get_org_subsystem_info(self) -> dict: 286 subsystem_info = {} 287 if self._os_level == "standard": 288 subsystem_info = IoUtil.read_json_file( 289 self._dirs.subsystem_config_json) 290 elif self._os_level == "mini" or self._os_level == "small": 291 ohos_build_output_dir = os.path.join(self._dirs.preloader_output_dir, 292 '{}_system'.format(self._os_level)) 293 subsystem_info = parse_lite_subsystem_config( 294 self._dirs.lite_components_dir, ohos_build_output_dir, 295 self._dirs.source_root_dir, self._dirs.subsystem_config_json) 296 return subsystem_info 297 298 def _get_compile_standard_whitelist_info(self) -> dict: 299 allow_info_file = "out/products_ext/{}/compile_standard_whitelist.json".format(self.config.product) 300 allow_info_file = os.path.join(self._dirs.source_root_dir, allow_info_file) 301 if not os.path.exists(allow_info_file): 302 allow_info_file = os.path.join(self._dirs.source_root_dir, "build/compile_standard_whitelist.json") 303 304 allow_info = IoUtil.read_json_file(allow_info_file) 305 return allow_info 306 307 def _get_compile_env_allowlist_info(self) -> dict: 308 allow_env_file = os.path.join( 309 self._dirs.source_root_dir, 310 "out/products_ext/{}/compile_env_allowlist.json".format( 311 self.config.product 312 ), 313 ) 314 if not os.path.exists(allow_env_file): 315 allow_env_file = os.path.join( 316 self._dirs.source_root_dir, "build/compile_env_allowlist.json" 317 ) 318 319 if not os.path.exists(allow_env_file): 320 return {} 321 322 allow_env = IoUtil.read_json_file(allow_env_file) 323 return allow_env 324