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