15f9996aaSopenharmony_ci#!/usr/bin/env python3 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci 45f9996aaSopenharmony_ci# 55f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 85f9996aaSopenharmony_ci# You may obtain a copy of the License at 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 115f9996aaSopenharmony_ci# 125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 165f9996aaSopenharmony_ci# limitations under the License. 175f9996aaSopenharmony_ci 185f9996aaSopenharmony_ciimport os 195f9996aaSopenharmony_ciimport stat 205f9996aaSopenharmony_ci 215f9996aaSopenharmony_cifrom services.interface.preload_interface import PreloadInterface 225f9996aaSopenharmony_cifrom util.io_util import IoUtil 235f9996aaSopenharmony_cifrom util.preloader.preloader_process_data import Dirs, Outputs, Product 245f9996aaSopenharmony_cifrom util.preloader.parse_lite_subsystems_config import parse_lite_subsystem_config 255f9996aaSopenharmony_cifrom util.log_util import LogUtil 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_ci 285f9996aaSopenharmony_ciclass OHOSPreloader(PreloadInterface): 295f9996aaSopenharmony_ci 305f9996aaSopenharmony_ci def __init__(self): 315f9996aaSopenharmony_ci super().__init__() 325f9996aaSopenharmony_ci self._dirs = "" 335f9996aaSopenharmony_ci self._outputs = "" 345f9996aaSopenharmony_ci self._product = "" 355f9996aaSopenharmony_ci self._os_level = "" 365f9996aaSopenharmony_ci self._target_cpu = "" 375f9996aaSopenharmony_ci self._target_os = "" 385f9996aaSopenharmony_ci self._toolchain_label = "" 395f9996aaSopenharmony_ci self._subsystem_info = {} 405f9996aaSopenharmony_ci self._all_parts = {} 415f9996aaSopenharmony_ci self._build_vars = {} 425f9996aaSopenharmony_ci self._compile_standard_whitelist_info = {} 435f9996aaSopenharmony_ci self._compile_env_allowlist_info = {} 445f9996aaSopenharmony_ci 455f9996aaSopenharmony_ci def __post_init__(self): 465f9996aaSopenharmony_ci self._dirs = Dirs(self._config) 475f9996aaSopenharmony_ci self._outputs = Outputs(self._dirs.preloader_output_dir) 485f9996aaSopenharmony_ci self._product = Product(self._dirs, self._config) 495f9996aaSopenharmony_ci self._all_parts = self._product._parts 505f9996aaSopenharmony_ci self._build_vars = self._product._build_vars 515f9996aaSopenharmony_ci self._os_level = self._build_vars.get('os_level') 525f9996aaSopenharmony_ci self._target_os = self._build_vars.get('target_os') 535f9996aaSopenharmony_ci self._target_cpu = self._build_vars.get('target_cpu') 545f9996aaSopenharmony_ci self._toolchain_label = self._build_vars.get('product_toolchain_label') 555f9996aaSopenharmony_ci self._subsystem_info = self._get_org_subsystem_info() 565f9996aaSopenharmony_ci self._compile_standard_whitelist_info = self._get_compile_standard_whitelist_info() 575f9996aaSopenharmony_ci self._compile_env_allowlist_info = self._get_compile_env_allowlist_info() 585f9996aaSopenharmony_ci 595f9996aaSopenharmony_ci# generate method 605f9996aaSopenharmony_ci 615f9996aaSopenharmony_ci '''Description: generate platforms build info to "out/preloader/{product_name}/platforms.build" 625f9996aaSopenharmony_ci @parameter:none 635f9996aaSopenharmony_ci @return :none 645f9996aaSopenharmony_ci ''' 655f9996aaSopenharmony_ci 665f9996aaSopenharmony_ci def _generate_platforms_build(self): 675f9996aaSopenharmony_ci config = { 685f9996aaSopenharmony_ci 'target_os': self._target_os, 695f9996aaSopenharmony_ci "target_cpu": self._target_cpu, 705f9996aaSopenharmony_ci "toolchain": self._toolchain_label, 715f9996aaSopenharmony_ci "parts_config": os.path.relpath(self._outputs.parts_json, 725f9996aaSopenharmony_ci self._dirs.preloader_output_dir) 735f9996aaSopenharmony_ci } 745f9996aaSopenharmony_ci platform_config = {'version': 2, 'platforms': {'phone': config}} 755f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.platforms_build, platform_config) 765f9996aaSopenharmony_ci LogUtil.hb_info( 775f9996aaSopenharmony_ci 'generated platforms build info to {}/platforms.build'.format( 785f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 795f9996aaSopenharmony_ci 805f9996aaSopenharmony_ci '''Description: generate build gnargs prop info to "out/preloader/{product_name}/build_gnargs.prop" 815f9996aaSopenharmony_ci @parameter:none 825f9996aaSopenharmony_ci @return :none 835f9996aaSopenharmony_ci ''' 845f9996aaSopenharmony_ci 855f9996aaSopenharmony_ci def _generate_build_gnargs_prop(self): 865f9996aaSopenharmony_ci all_features = {} 875f9996aaSopenharmony_ci for _part_name, vals in self._all_parts.items(): 885f9996aaSopenharmony_ci _features = vals.get('features') 895f9996aaSopenharmony_ci if _features: 905f9996aaSopenharmony_ci all_features.update(_features) 915f9996aaSopenharmony_ci attr_list = [] 925f9996aaSopenharmony_ci for key, val in all_features.items(): 935f9996aaSopenharmony_ci _item = '' 945f9996aaSopenharmony_ci if isinstance(val, bool): 955f9996aaSopenharmony_ci _item = f'{key}={str(val).lower()}' 965f9996aaSopenharmony_ci elif isinstance(val, int): 975f9996aaSopenharmony_ci _item = f'{key}={val}' 985f9996aaSopenharmony_ci elif isinstance(val, str): 995f9996aaSopenharmony_ci _item = f'{key}="{val}"' 1005f9996aaSopenharmony_ci else: 1015f9996aaSopenharmony_ci raise Exception("part feature '{key}:{val}' type not support.") 1025f9996aaSopenharmony_ci attr_list.append(_item) 1035f9996aaSopenharmony_ci with os.fdopen(os.open(self._outputs.build_gnargs_prop, 1045f9996aaSopenharmony_ci os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 1055f9996aaSopenharmony_ci fobj.write('\n'.join(attr_list)) 1065f9996aaSopenharmony_ci LogUtil.hb_info( 1075f9996aaSopenharmony_ci 'generated build gnargs prop info to {}/build_gnargs.prop'.format( 1085f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 1095f9996aaSopenharmony_ci 1105f9996aaSopenharmony_ci '''Description: generate features to "out/preloader/{product_name}/features.json" 1115f9996aaSopenharmony_ci @parameter:none 1125f9996aaSopenharmony_ci @return :none 1135f9996aaSopenharmony_ci ''' 1145f9996aaSopenharmony_ci 1155f9996aaSopenharmony_ci def _generate_features_json(self): 1165f9996aaSopenharmony_ci all_features = {} 1175f9996aaSopenharmony_ci part_feature_map = {} 1185f9996aaSopenharmony_ci for _part_name, vals in self._all_parts.items(): 1195f9996aaSopenharmony_ci _features = vals.get('features') 1205f9996aaSopenharmony_ci if _features: 1215f9996aaSopenharmony_ci all_features.update(_features) 1225f9996aaSopenharmony_ci if _features: 1235f9996aaSopenharmony_ci part_feature_map[_part_name.split( 1245f9996aaSopenharmony_ci ':')[1]] = list(_features.keys()) 1255f9996aaSopenharmony_ci parts_feature_info = { 1265f9996aaSopenharmony_ci "features": all_features, 1275f9996aaSopenharmony_ci "part_to_feature": part_feature_map 1285f9996aaSopenharmony_ci } 1295f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.features_json, parts_feature_info) 1305f9996aaSopenharmony_ci LogUtil.hb_info( 1315f9996aaSopenharmony_ci 'generated features info to {}/features.json'.format( 1325f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 1335f9996aaSopenharmony_ci 1345f9996aaSopenharmony_ci '''Description: generate syscap to "out/preloader/product_name/syscap.json" 1355f9996aaSopenharmony_ci @parameter:none 1365f9996aaSopenharmony_ci @return :none 1375f9996aaSopenharmony_ci ''' 1385f9996aaSopenharmony_ci 1395f9996aaSopenharmony_ci def _generate_syscap_json(self): 1405f9996aaSopenharmony_ci all_syscap = {} 1415f9996aaSopenharmony_ci part_syscap_map = {} 1425f9996aaSopenharmony_ci for _part_name, vals in self._all_parts.items(): 1435f9996aaSopenharmony_ci _syscap = vals.get('syscap') 1445f9996aaSopenharmony_ci if _syscap: 1455f9996aaSopenharmony_ci all_syscap.update(_syscap) 1465f9996aaSopenharmony_ci part_syscap_map[_part_name.split(':')[1]] = _syscap 1475f9996aaSopenharmony_ci parts_syscap_info = { 1485f9996aaSopenharmony_ci "syscap": all_syscap, 1495f9996aaSopenharmony_ci "part_to_syscap": part_syscap_map 1505f9996aaSopenharmony_ci } 1515f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.syscap_json, parts_syscap_info) 1525f9996aaSopenharmony_ci LogUtil.hb_info( 1535f9996aaSopenharmony_ci 'generated syscap info to {}/syscap.json'.format( 1545f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 1555f9996aaSopenharmony_ci 1565f9996aaSopenharmony_ci '''Description: generate exclusion modules info to "out/preloader/product_name/exclusion_modules.json" 1575f9996aaSopenharmony_ci @parameter:none 1585f9996aaSopenharmony_ci @return :none 1595f9996aaSopenharmony_ci ''' 1605f9996aaSopenharmony_ci 1615f9996aaSopenharmony_ci def _generate_exclusion_modules_json(self): 1625f9996aaSopenharmony_ci exclusions = {} 1635f9996aaSopenharmony_ci for _part_name, vals in self._all_parts.items(): 1645f9996aaSopenharmony_ci _exclusions = vals.get('exclusions') 1655f9996aaSopenharmony_ci if _exclusions: 1665f9996aaSopenharmony_ci pair = dict() 1675f9996aaSopenharmony_ci pair[_part_name] = _exclusions 1685f9996aaSopenharmony_ci exclusions.update(pair) 1695f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.exclusion_modules_json, exclusions) 1705f9996aaSopenharmony_ci LogUtil.hb_info( 1715f9996aaSopenharmony_ci 'generated exclusion modules info to {}/exclusion_modules.json'.format( 1725f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 1735f9996aaSopenharmony_ci 1745f9996aaSopenharmony_ci '''Description: generate build config info to "out/preloader/product_name/build_config.json" 1755f9996aaSopenharmony_ci @parameter:none 1765f9996aaSopenharmony_ci @return :none 1775f9996aaSopenharmony_ci ''' 1785f9996aaSopenharmony_ci 1795f9996aaSopenharmony_ci def _generate_build_config_json(self): 1805f9996aaSopenharmony_ci IoUtil.dump_json_file( 1815f9996aaSopenharmony_ci self._outputs.build_config_json, self._build_vars) 1825f9996aaSopenharmony_ci LogUtil.hb_info( 1835f9996aaSopenharmony_ci 'generated build config info to {}/build_config.json'.format( 1845f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 1855f9996aaSopenharmony_ci 1865f9996aaSopenharmony_ci '''Description: generate build prop info to "out/preloader/product_name/build.prop" 1875f9996aaSopenharmony_ci @parameter:none 1885f9996aaSopenharmony_ci @return :none 1895f9996aaSopenharmony_ci ''' 1905f9996aaSopenharmony_ci 1915f9996aaSopenharmony_ci def _generate_build_prop(self): 1925f9996aaSopenharmony_ci build_vars_list = [] 1935f9996aaSopenharmony_ci for key, value in self._build_vars.items(): 1945f9996aaSopenharmony_ci build_vars_list.append('{}={}'.format(key, value)) 1955f9996aaSopenharmony_ci with os.fdopen(os.open(self._outputs.build_prop, 1965f9996aaSopenharmony_ci os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj: 1975f9996aaSopenharmony_ci fobj.write('\n'.join(build_vars_list)) 1985f9996aaSopenharmony_ci LogUtil.hb_info( 1995f9996aaSopenharmony_ci 'generated build prop info to {}/build.prop'.format( 2005f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 2015f9996aaSopenharmony_ci 2025f9996aaSopenharmony_ci '''Description: generate parts to "out/preloader/product_name/parts.json" 2035f9996aaSopenharmony_ci @parameter:none 2045f9996aaSopenharmony_ci @return :none 2055f9996aaSopenharmony_ci ''' 2065f9996aaSopenharmony_ci 2075f9996aaSopenharmony_ci def _generate_parts_json(self): 2085f9996aaSopenharmony_ci parts_info = {"parts": sorted(list(self._all_parts.keys()))} 2095f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.parts_json, parts_info) 2105f9996aaSopenharmony_ci LogUtil.hb_info( 2115f9996aaSopenharmony_ci 'generated product parts info to {}/parts.json'.format( 2125f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 2135f9996aaSopenharmony_ci 2145f9996aaSopenharmony_ci '''Description: generate parts config to "out/preloader/product_name/parts_config.json" 2155f9996aaSopenharmony_ci @parameter:none 2165f9996aaSopenharmony_ci @return :none 2175f9996aaSopenharmony_ci ''' 2185f9996aaSopenharmony_ci 2195f9996aaSopenharmony_ci def _generate_parts_config_json(self): 2205f9996aaSopenharmony_ci parts_config = {} 2215f9996aaSopenharmony_ci for part in self._all_parts: 2225f9996aaSopenharmony_ci part = part.replace(":", "_") 2235f9996aaSopenharmony_ci part = part.replace("-", "_") 2245f9996aaSopenharmony_ci part = part.replace(".", "_") 2255f9996aaSopenharmony_ci part = part.replace("/", "_") 2265f9996aaSopenharmony_ci parts_config[part] = True 2275f9996aaSopenharmony_ci IoUtil.dump_json_file(self._outputs.parts_config_json, parts_config) 2285f9996aaSopenharmony_ci LogUtil.hb_info( 2295f9996aaSopenharmony_ci 'generated parts config info to {}/parts_config.json'.format( 2305f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 2315f9996aaSopenharmony_ci 2325f9996aaSopenharmony_ci '''Description: generate subsystem config info to "out/preloader/product_name/subsystem_config.json" 2335f9996aaSopenharmony_ci @parameter:none 2345f9996aaSopenharmony_ci @return :none 2355f9996aaSopenharmony_ci ''' 2365f9996aaSopenharmony_ci 2375f9996aaSopenharmony_ci def _generate_subsystem_config_json(self): 2385f9996aaSopenharmony_ci if self._subsystem_info: 2395f9996aaSopenharmony_ci self._subsystem_info.update( 2405f9996aaSopenharmony_ci self._product._get_product_specific_subsystem()) 2415f9996aaSopenharmony_ci self._subsystem_info.update( 2425f9996aaSopenharmony_ci self._product._get_device_specific_subsystem()) 2435f9996aaSopenharmony_ci IoUtil.dump_json_file( 2445f9996aaSopenharmony_ci self._outputs.subsystem_config_json, self._subsystem_info) 2455f9996aaSopenharmony_ci LogUtil.hb_info( 2465f9996aaSopenharmony_ci 'generated subsystem config info to {}/subsystem_config.json'.format( 2475f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 2485f9996aaSopenharmony_ci 2495f9996aaSopenharmony_ci '''Description: generate systemcapability_json to "out/preloader/product_name/systemcapability.json" 2505f9996aaSopenharmony_ci @parameter:none 2515f9996aaSopenharmony_ci @return :none 2525f9996aaSopenharmony_ci ''' 2535f9996aaSopenharmony_ci 2545f9996aaSopenharmony_ci def _generate_systemcapability_json(self): 2555f9996aaSopenharmony_ci IoUtil.dump_json_file( 2565f9996aaSopenharmony_ci self._outputs.systemcapability_json, self._product._syscap_info) 2575f9996aaSopenharmony_ci LogUtil.hb_info( 2585f9996aaSopenharmony_ci 'generated system capability info to {}/systemcapability.json'.format( 2595f9996aaSopenharmony_ci self._dirs.preloader_output_dir), mode=self.config.log_mode) 2605f9996aaSopenharmony_ci 2615f9996aaSopenharmony_ci '''Description: generate compile_standard_whitelist info to "out/preloader/product_name/compile_standard_whitelist.json" 2625f9996aaSopenharmony_ci @parameter:none 2635f9996aaSopenharmony_ci @return :none 2645f9996aaSopenharmony_ci ''' 2655f9996aaSopenharmony_ci 2665f9996aaSopenharmony_ci def _generate_compile_standard_whitelist_json(self): 2675f9996aaSopenharmony_ci IoUtil.dump_json_file( 2685f9996aaSopenharmony_ci self._outputs.compile_standard_whitelist_json, self._compile_standard_whitelist_info) 2695f9996aaSopenharmony_ci LogUtil.hb_info( 2705f9996aaSopenharmony_ci 'generated compile_standard_whitelist info to {}/compile_standard_whitelist.json' 2715f9996aaSopenharmony_ci .format(self._dirs.preloader_output_dir), mode=self.config.log_mode) 2725f9996aaSopenharmony_ci 2735f9996aaSopenharmony_ci def _generate_compile_env_allowlist_json(self): 2745f9996aaSopenharmony_ci IoUtil.dump_json_file( 2755f9996aaSopenharmony_ci self._outputs.compile_env_allowlist_json, self._compile_env_allowlist_info 2765f9996aaSopenharmony_ci ) 2775f9996aaSopenharmony_ci LogUtil.hb_info( 2785f9996aaSopenharmony_ci "generated compile_env_allowlist info to {}/compile_env_allowlist.json".format( 2795f9996aaSopenharmony_ci self._dirs.preloader_output_dir 2805f9996aaSopenharmony_ci ) 2815f9996aaSopenharmony_ci ) 2825f9996aaSopenharmony_ci 2835f9996aaSopenharmony_ci# get method 2845f9996aaSopenharmony_ci 2855f9996aaSopenharmony_ci def _get_org_subsystem_info(self) -> dict: 2865f9996aaSopenharmony_ci subsystem_info = {} 2875f9996aaSopenharmony_ci if self._os_level == "standard": 2885f9996aaSopenharmony_ci subsystem_info = IoUtil.read_json_file( 2895f9996aaSopenharmony_ci self._dirs.subsystem_config_json) 2905f9996aaSopenharmony_ci elif self._os_level == "mini" or self._os_level == "small": 2915f9996aaSopenharmony_ci ohos_build_output_dir = os.path.join(self._dirs.preloader_output_dir, 2925f9996aaSopenharmony_ci '{}_system'.format(self._os_level)) 2935f9996aaSopenharmony_ci subsystem_info = parse_lite_subsystem_config( 2945f9996aaSopenharmony_ci self._dirs.lite_components_dir, ohos_build_output_dir, 2955f9996aaSopenharmony_ci self._dirs.source_root_dir, self._dirs.subsystem_config_json) 2965f9996aaSopenharmony_ci return subsystem_info 2975f9996aaSopenharmony_ci 2985f9996aaSopenharmony_ci def _get_compile_standard_whitelist_info(self) -> dict: 2995f9996aaSopenharmony_ci allow_info_file = "out/products_ext/{}/compile_standard_whitelist.json".format(self.config.product) 3005f9996aaSopenharmony_ci allow_info_file = os.path.join(self._dirs.source_root_dir, allow_info_file) 3015f9996aaSopenharmony_ci if not os.path.exists(allow_info_file): 3025f9996aaSopenharmony_ci allow_info_file = os.path.join(self._dirs.source_root_dir, "build/compile_standard_whitelist.json") 3035f9996aaSopenharmony_ci 3045f9996aaSopenharmony_ci allow_info = IoUtil.read_json_file(allow_info_file) 3055f9996aaSopenharmony_ci return allow_info 3065f9996aaSopenharmony_ci 3075f9996aaSopenharmony_ci def _get_compile_env_allowlist_info(self) -> dict: 3085f9996aaSopenharmony_ci allow_env_file = os.path.join( 3095f9996aaSopenharmony_ci self._dirs.source_root_dir, 3105f9996aaSopenharmony_ci "out/products_ext/{}/compile_env_allowlist.json".format( 3115f9996aaSopenharmony_ci self.config.product 3125f9996aaSopenharmony_ci ), 3135f9996aaSopenharmony_ci ) 3145f9996aaSopenharmony_ci if not os.path.exists(allow_env_file): 3155f9996aaSopenharmony_ci allow_env_file = os.path.join( 3165f9996aaSopenharmony_ci self._dirs.source_root_dir, "build/compile_env_allowlist.json" 3175f9996aaSopenharmony_ci ) 3185f9996aaSopenharmony_ci 3195f9996aaSopenharmony_ci if not os.path.exists(allow_env_file): 3205f9996aaSopenharmony_ci return {} 3215f9996aaSopenharmony_ci 3225f9996aaSopenharmony_ci allow_env = IoUtil.read_json_file(allow_env_file) 3235f9996aaSopenharmony_ci return allow_env 324