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 json 205f9996aaSopenharmony_ciimport copy 215f9996aaSopenharmony_ci 225f9996aaSopenharmony_cifrom services.interface.load_interface import LoadInterface 235f9996aaSopenharmony_cifrom containers.status import throw_exception 245f9996aaSopenharmony_cifrom exceptions.ohos_exception import OHOSException 255f9996aaSopenharmony_cifrom util.loader import platforms_loader # noqa: E402 265f9996aaSopenharmony_cifrom util.loader import generate_targets_gn # noqa: E402 275f9996aaSopenharmony_cifrom util.loader import load_ohos_build # noqa: E402 285f9996aaSopenharmony_cifrom util.loader import subsystem_scan # noqa: E402 295f9996aaSopenharmony_cifrom util.loader import subsystem_info # noqa: E402 305f9996aaSopenharmony_cifrom scripts.util.file_utils import read_json_file, write_json_file, write_file # noqa: E402, E501 315f9996aaSopenharmony_cifrom util.log_util import LogUtil 325f9996aaSopenharmony_cifrom resources.config import Config 335f9996aaSopenharmony_ci 345f9996aaSopenharmony_ci 355f9996aaSopenharmony_ciclass OHOSLoader(LoadInterface): 365f9996aaSopenharmony_ci 375f9996aaSopenharmony_ci def __init__(self): 385f9996aaSopenharmony_ci super().__init__() 395f9996aaSopenharmony_ci self.source_root_dir = "" 405f9996aaSopenharmony_ci self.gn_root_out_dir = "" 415f9996aaSopenharmony_ci self.os_level = "" 425f9996aaSopenharmony_ci self.target_cpu = "" 435f9996aaSopenharmony_ci self.target_os = "" 445f9996aaSopenharmony_ci self.config_output_relpath = "" 455f9996aaSopenharmony_ci self.config_output_dir = "" 465f9996aaSopenharmony_ci self.target_arch = "" 475f9996aaSopenharmony_ci self.subsystem_config_file = "" 485f9996aaSopenharmony_ci self.subsystem_config_overlay_file = "" 495f9996aaSopenharmony_ci self.platforms_config_file = "" 505f9996aaSopenharmony_ci self.exclusion_modules_config_file = "" 515f9996aaSopenharmony_ci self.example_subsystem_file = "" 525f9996aaSopenharmony_ci self.build_example = "" 535f9996aaSopenharmony_ci self.scalable_build = "" 545f9996aaSopenharmony_ci self.build_platform_name = "" 555f9996aaSopenharmony_ci self.build_xts = "" 565f9996aaSopenharmony_ci self.ignore_api_check = "" 575f9996aaSopenharmony_ci self.load_test_config = "" 585f9996aaSopenharmony_ci self.subsystem_configs = "" 595f9996aaSopenharmony_ci self._subsystem_info = "" 605f9996aaSopenharmony_ci self.skip_partlist_check = "" 615f9996aaSopenharmony_ci 625f9996aaSopenharmony_ci def __post_init__(self): 635f9996aaSopenharmony_ci self.source_root_dir = self.config.root_path + '/' 645f9996aaSopenharmony_ci self.gn_root_out_dir = self.config.out_path if not self.config.out_path.startswith( 655f9996aaSopenharmony_ci '/') else os.path.relpath(self.config.out_path, self.config.root_path) 665f9996aaSopenharmony_ci self.os_level = self.config.os_level if self.config.os_level else "standard" 675f9996aaSopenharmony_ci self.target_cpu = self.config.target_cpu if self.config.target_cpu else "arm" 685f9996aaSopenharmony_ci self.target_os = self.config.target_os if self.config.target_os else "ohos" 695f9996aaSopenharmony_ci self.config_output_relpath = os.path.join( 705f9996aaSopenharmony_ci self.gn_root_out_dir, 'build_configs') 715f9996aaSopenharmony_ci self.config_output_dir = os.path.join( 725f9996aaSopenharmony_ci self.source_root_dir, self.config_output_relpath) 735f9996aaSopenharmony_ci self.target_arch = '{}_{}'.format(self.target_os, self.target_cpu) 745f9996aaSopenharmony_ci self.subsystem_config_file = os.path.join( 755f9996aaSopenharmony_ci self.config.root_path, 'out/preloader', self.config.product, 'subsystem_config.json') 765f9996aaSopenharmony_ci self.platforms_config_file = os.path.join( 775f9996aaSopenharmony_ci self.config.root_path, 'out/preloader', self.config.product, 'platforms.build') 785f9996aaSopenharmony_ci self.exclusion_modules_config_file = os.path.join( 795f9996aaSopenharmony_ci self.config.root_path, 'out/preloader', self.config.product, 'exclusion_modules.json') 805f9996aaSopenharmony_ci self.example_subsystem_file = os.path.join( 815f9996aaSopenharmony_ci self.config.root_path, 'build', 'subsystem_config_example.json') 825f9996aaSopenharmony_ci self.parts_src_file = os.path.join( 835f9996aaSopenharmony_ci self.config_output_dir, 'parts_src_flag.json') 845f9996aaSopenharmony_ci self.auto_install_file = os.path.join( 855f9996aaSopenharmony_ci self.config_output_dir, 'auto_install_parts.json') 865f9996aaSopenharmony_ci self.components_file = os.path.join( 875f9996aaSopenharmony_ci self.config_output_dir, 'parts_info', 'components.json') 885f9996aaSopenharmony_ci 895f9996aaSopenharmony_ci compile_standard_allow_file = os.path.join( 905f9996aaSopenharmony_ci self.config.root_path, 'out/preloader', self.config.product, 'compile_standard_whitelist.json') 915f9996aaSopenharmony_ci compile_standard_allow_info = read_json_file(compile_standard_allow_file) 925f9996aaSopenharmony_ci bundle_subsystem_allow_list = compile_standard_allow_info.get("bundle_subsystem_error", []) 935f9996aaSopenharmony_ci 945f9996aaSopenharmony_ci # check config args 955f9996aaSopenharmony_ci self._check_args() 965f9996aaSopenharmony_ci 975f9996aaSopenharmony_ci self.build_example = self.args_dict.get('build_example') 985f9996aaSopenharmony_ci if not self.build_example: 995f9996aaSopenharmony_ci self.example_subsystem_file = "" 1005f9996aaSopenharmony_ci self.scalable_build = self.args_dict.get('scalable_build') 1015f9996aaSopenharmony_ci self.build_platform_name = self.args_dict.get('build_platform_name') 1025f9996aaSopenharmony_ci self.build_xts = self.args_dict.get('build_xts') 1035f9996aaSopenharmony_ci self.ignore_api_check = self.args_dict.get('ignore_api_check') 1045f9996aaSopenharmony_ci self.load_test_config = self.args_dict.get('load_test_config') 1055f9996aaSopenharmony_ci self.skip_partlist_check = self.args_dict.get('skip_partlist_check') 1065f9996aaSopenharmony_ci 1075f9996aaSopenharmony_ci self._subsystem_info = subsystem_info.get_subsystem_info( 1085f9996aaSopenharmony_ci self.subsystem_config_file, 1095f9996aaSopenharmony_ci self.example_subsystem_file, 1105f9996aaSopenharmony_ci self.source_root_dir, 1115f9996aaSopenharmony_ci self.config_output_relpath, 1125f9996aaSopenharmony_ci self.os_level) 1135f9996aaSopenharmony_ci overrided_components = self._override_components() 1145f9996aaSopenharmony_ci 1155f9996aaSopenharmony_ci self._platforms_info = platforms_loader.get_platforms_info( 1165f9996aaSopenharmony_ci self.platforms_config_file, 1175f9996aaSopenharmony_ci self.source_root_dir, 1185f9996aaSopenharmony_ci self.gn_root_out_dir, 1195f9996aaSopenharmony_ci self.target_arch, 1205f9996aaSopenharmony_ci self.config_output_relpath, 1215f9996aaSopenharmony_ci self.scalable_build) 1225f9996aaSopenharmony_ci self.variant_toolchains = self._platforms_info.get( 1235f9996aaSopenharmony_ci 'variant_toolchain_info').get('platform_toolchain') 1245f9996aaSopenharmony_ci self._all_platforms = self.variant_toolchains.keys() 1255f9996aaSopenharmony_ci self.build_platforms = self._get_build_platforms() 1265f9996aaSopenharmony_ci self.parts_config_info = load_ohos_build.get_parts_info( 1275f9996aaSopenharmony_ci self.source_root_dir, 1285f9996aaSopenharmony_ci self.config_output_relpath, 1295f9996aaSopenharmony_ci self._subsystem_info, 1305f9996aaSopenharmony_ci self.variant_toolchains, 1315f9996aaSopenharmony_ci self.target_arch, 1325f9996aaSopenharmony_ci self.ignore_api_check, 1335f9996aaSopenharmony_ci self.exclusion_modules_config_file, 1345f9996aaSopenharmony_ci self.load_test_config, 1355f9996aaSopenharmony_ci overrided_components, 1365f9996aaSopenharmony_ci bundle_subsystem_allow_list, 1375f9996aaSopenharmony_ci self.skip_partlist_check, 1385f9996aaSopenharmony_ci self.build_xts) 1395f9996aaSopenharmony_ci self.parts_targets = self.parts_config_info.get('parts_targets') 1405f9996aaSopenharmony_ci self.phony_targets = self.parts_config_info.get('phony_target') 1415f9996aaSopenharmony_ci self.parts_info = self.parts_config_info.get('parts_info') 1425f9996aaSopenharmony_ci self.target_platform_parts = self._get_platforms_all_parts() 1435f9996aaSopenharmony_ci self.target_platform_stubs = self._get_platforms_all_stubs() 1445f9996aaSopenharmony_ci self.required_parts_targets_list = self._get_required_build_parts_list() 1455f9996aaSopenharmony_ci self.required_phony_targets = self._get_required_phony_targets() 1465f9996aaSopenharmony_ci self.required_parts_targets = self._get_required_build_targets() 1475f9996aaSopenharmony_ci 1485f9996aaSopenharmony_ci 1495f9996aaSopenharmony_ci @throw_exception 1505f9996aaSopenharmony_ci def _merge_components_info(self, components): 1515f9996aaSopenharmony_ci config = Config() 1525f9996aaSopenharmony_ci sdk_components_file = os.path.join(config.root_path, "out/products_ext/components.json") 1535f9996aaSopenharmony_ci if not os.path.exists(sdk_components_file): 1545f9996aaSopenharmony_ci return 1555f9996aaSopenharmony_ci 1565f9996aaSopenharmony_ci sdk_components_info = read_json_file(sdk_components_file) 1575f9996aaSopenharmony_ci for name, val in sdk_components_info.items(): 1585f9996aaSopenharmony_ci if name not in components.keys(): 1595f9996aaSopenharmony_ci components[name] = val 1605f9996aaSopenharmony_ci 1615f9996aaSopenharmony_ci 1625f9996aaSopenharmony_ci @throw_exception 1635f9996aaSopenharmony_ci def _cropping_components(self): 1645f9996aaSopenharmony_ci src_parts = read_json_file(self.parts_src_file) 1655f9996aaSopenharmony_ci 1665f9996aaSopenharmony_ci auto_parts = read_json_file(self.auto_install_file) 1675f9996aaSopenharmony_ci 1685f9996aaSopenharmony_ci self.third_party_file = os.path.join(self.config.root_path, "out/products_ext/third_party_allow_list.json") 1695f9996aaSopenharmony_ci if not os.path.exists(self.third_party_file): 1705f9996aaSopenharmony_ci self.third_party_file = os.path.join(self.config.root_path, 'build/third_party_allow_list.json') 1715f9996aaSopenharmony_ci cropping_parts = read_json_file(self.third_party_file) 1725f9996aaSopenharmony_ci 1735f9996aaSopenharmony_ci components_data = read_json_file(self.components_file) 1745f9996aaSopenharmony_ci 1755f9996aaSopenharmony_ci new_components_data = copy.deepcopy(components_data) 1765f9996aaSopenharmony_ci 1775f9996aaSopenharmony_ci for component, component_value in components_data.items(): 1785f9996aaSopenharmony_ci if component not in src_parts and component not in auto_parts and component not in cropping_parts: 1795f9996aaSopenharmony_ci del new_components_data[component] 1805f9996aaSopenharmony_ci self._merge_components_info(new_components_data) 1815f9996aaSopenharmony_ci os.remove(self.components_file) 1825f9996aaSopenharmony_ci write_json_file(self.components_file, new_components_data) 1835f9996aaSopenharmony_ci 1845f9996aaSopenharmony_ci 1855f9996aaSopenharmony_ci# check method 1865f9996aaSopenharmony_ci 1875f9996aaSopenharmony_ci '''Description: Check the parameters passed in config. If the parameters are not 1885f9996aaSopenharmony_ci specified or the file content pointed to by the parameters does not 1895f9996aaSopenharmony_ci exist, an exception will be thrown directly. 1905f9996aaSopenharmony_ci @parameter:none 1915f9996aaSopenharmony_ci @return :none 1925f9996aaSopenharmony_ci ''' 1935f9996aaSopenharmony_ci @throw_exception 1945f9996aaSopenharmony_ci def _check_args(self): 1955f9996aaSopenharmony_ci LogUtil.hb_info("Checking all build args...") 1965f9996aaSopenharmony_ci # check subsystem_config_file 1975f9996aaSopenharmony_ci if not read_json_file(self.subsystem_config_file): 1985f9996aaSopenharmony_ci self.subsystem_config_file = os.path.join( 1995f9996aaSopenharmony_ci self.source_root_dir, 'build/subsystem_config.json') 2005f9996aaSopenharmony_ci if not read_json_file(self.subsystem_config_file): 2015f9996aaSopenharmony_ci raise OHOSException("Cannot get the content from platform config file, \ 2025f9996aaSopenharmony_ci please check whether the corresponding file('out/preloader/{}/subsystem_config.json' or \ 2035f9996aaSopenharmony_ci 'build/subsystem_config.json') is written correctly.".format(self.config.product), "2001") 2045f9996aaSopenharmony_ci 2055f9996aaSopenharmony_ci # check gn_root_out_dir 2065f9996aaSopenharmony_ci if not self.gn_root_out_dir: 2075f9996aaSopenharmony_ci raise OHOSException("Args gn_root_out_dir is required.", "2002") 2085f9996aaSopenharmony_ci if not os.path.realpath(self.gn_root_out_dir).startswith(self.source_root_dir): 2095f9996aaSopenharmony_ci raise OHOSException("Args gn_root_out_dir is incorrect.", "2003") 2105f9996aaSopenharmony_ci 2115f9996aaSopenharmony_ci # check platform config file 2125f9996aaSopenharmony_ci if not read_json_file(self.platforms_config_file): 2135f9996aaSopenharmony_ci raise OHOSException("Cannot get the content from platform config file, \ 2145f9996aaSopenharmony_ci please check whether the corresponding file('out/preloader/${product_name}/platforms.build') \ 2155f9996aaSopenharmony_ci is written correctly.".format(self.config.product), "2004") 2165f9996aaSopenharmony_ci 2175f9996aaSopenharmony_ci # check example subsystem file 2185f9996aaSopenharmony_ci if not read_json_file(self.example_subsystem_file): 2195f9996aaSopenharmony_ci raise OHOSException("Cannot get the content from example subsystem file, please check whether \ 2205f9996aaSopenharmony_ci the corresponding file ('build/subsystem_config_example.json') exists.", "2005") 2215f9996aaSopenharmony_ci 2225f9996aaSopenharmony_ci @throw_exception 2235f9996aaSopenharmony_ci def _check_product_part_feature(self): 2245f9996aaSopenharmony_ci LogUtil.hb_info("Checking all product features...") 2255f9996aaSopenharmony_ci product_preloader_dir = os.path.dirname(self.platforms_config_file) 2265f9996aaSopenharmony_ci _preloader_feature_file = os.path.join(product_preloader_dir, 2275f9996aaSopenharmony_ci 'features.json') 2285f9996aaSopenharmony_ci _preloader_feature_info = read_json_file(_preloader_feature_file) 2295f9996aaSopenharmony_ci part_to_feature = _preloader_feature_info.get('part_to_feature') 2305f9996aaSopenharmony_ci _feature_whitelist_file = os.path.join( 2315f9996aaSopenharmony_ci self.source_root_dir, "out/products_ext", "component_feature_whitelist.json" 2325f9996aaSopenharmony_ci ) 2335f9996aaSopenharmony_ci if not os.path.exists(_feature_whitelist_file): 2345f9996aaSopenharmony_ci _feature_whitelist_file = os.path.join( 2355f9996aaSopenharmony_ci self.source_root_dir, "build/", "component_feature_whitelist.json" 2365f9996aaSopenharmony_ci ) 2375f9996aaSopenharmony_ci _feature_whitelist_info = read_json_file(_feature_whitelist_file) 2385f9996aaSopenharmony_ci _feature_whitelist_list = [] 2395f9996aaSopenharmony_ci if _feature_whitelist_info: 2405f9996aaSopenharmony_ci _feature_whitelist_list = list(_feature_whitelist_info.keys()) 2415f9996aaSopenharmony_ci for key, vals in part_to_feature.items(): 2425f9996aaSopenharmony_ci part = self.parts_info.get(key) 2435f9996aaSopenharmony_ci if part is None: 2445f9996aaSopenharmony_ci continue 2455f9996aaSopenharmony_ci _p_info = part[0] 2465f9996aaSopenharmony_ci def_feature_list = _p_info.get('feature_list') 2475f9996aaSopenharmony_ci if vals and not def_feature_list: 2485f9996aaSopenharmony_ci message = "The product use a feature vals='{}', but that is not defined " \ 2495f9996aaSopenharmony_ci "in this part bundle.json file, part_name='{}'".format(vals, key) 2505f9996aaSopenharmony_ci if key not in _feature_whitelist_list: 2515f9996aaSopenharmony_ci raise OHOSException(message, "2006") 2525f9996aaSopenharmony_ci LogUtil.hb_warning(message) 2535f9996aaSopenharmony_ci continue 2545f9996aaSopenharmony_ci for _f_name in vals: 2555f9996aaSopenharmony_ci if _f_name not in def_feature_list: 2565f9996aaSopenharmony_ci raise OHOSException( 2575f9996aaSopenharmony_ci "The product use a feature that is not supported" 2585f9996aaSopenharmony_ci " by this part, part_name='{}', feature='{}'".format( 2595f9996aaSopenharmony_ci key, _f_name), "2006") 2605f9996aaSopenharmony_ci 2615f9996aaSopenharmony_ci @throw_exception 2625f9996aaSopenharmony_ci def _check_parts_config_info(self): 2635f9996aaSopenharmony_ci LogUtil.hb_info("Checking parts config...") 2645f9996aaSopenharmony_ci if not ('parts_info' in self.parts_config_info 2655f9996aaSopenharmony_ci and 'subsystem_parts' in self.parts_config_info 2665f9996aaSopenharmony_ci and 'parts_variants' in self.parts_config_info 2675f9996aaSopenharmony_ci and 'parts_kits_info' in self.parts_config_info 2685f9996aaSopenharmony_ci and 'parts_inner_kits_info' in self.parts_config_info 2695f9996aaSopenharmony_ci and 'parts_targets' in self.parts_config_info): 2705f9996aaSopenharmony_ci raise OHOSException( 2715f9996aaSopenharmony_ci "Loading ohos.build information is incorrect.", "2007") 2725f9996aaSopenharmony_ci 2735f9996aaSopenharmony_ci# generate method 2745f9996aaSopenharmony_ci 2755f9996aaSopenharmony_ci '''Description: Generate SystemCapability.json & syscap.json & syscap.para, dir:[ 2765f9996aaSopenharmony_ci (//out/preloader/${product_name}/system/etc/SystemCapability.json), 2775f9996aaSopenharmony_ci (//out/preloader/${product_name}/system/etc/syscap.json), 2785f9996aaSopenharmony_ci (//out/preloader/${product_name}/system/etc/param/syscap.para)] 2795f9996aaSopenharmony_ci @parameter:none 2805f9996aaSopenharmony_ci @return :none 2815f9996aaSopenharmony_ci ''' 2825f9996aaSopenharmony_ci @throw_exception 2835f9996aaSopenharmony_ci def _generate_syscap_files(self): 2845f9996aaSopenharmony_ci pre_syscap_info_path = os.path.dirname(self.platforms_config_file) 2855f9996aaSopenharmony_ci system_path = os.path.join(self.source_root_dir, os.path.join( 2865f9996aaSopenharmony_ci os.path.dirname(self.platforms_config_file), "system/")) 2875f9996aaSopenharmony_ci syscap_product_dict = read_json_file( 2885f9996aaSopenharmony_ci os.path.join(pre_syscap_info_path, "syscap.json")) 2895f9996aaSopenharmony_ci syscap_info_list = self.parts_config_info.get('syscap_info') 2905f9996aaSopenharmony_ci target_syscap_with_part_name_list = [] 2915f9996aaSopenharmony_ci target_syscap_list = [] 2925f9996aaSopenharmony_ci target_syscap_for_init_list = [] 2935f9996aaSopenharmony_ci all_syscap_list = [] 2945f9996aaSopenharmony_ci for syscap in syscap_info_list: 2955f9996aaSopenharmony_ci if syscap['component'] not in self.required_parts_targets_list: 2965f9996aaSopenharmony_ci continue 2975f9996aaSopenharmony_ci if 'syscap' not in syscap or syscap['syscap'] is None \ 2985f9996aaSopenharmony_ci or len(syscap['syscap']) == 0 or syscap['syscap'] == [""]: 2995f9996aaSopenharmony_ci continue 3005f9996aaSopenharmony_ci for syscap_string in syscap['syscap']: 3015f9996aaSopenharmony_ci all_syscap_list.append(syscap_string.split('=')[0].strip()) 3025f9996aaSopenharmony_ci 3035f9996aaSopenharmony_ci for key, value in syscap_product_dict['part_to_syscap'].items(): 3045f9996aaSopenharmony_ci part = self.parts_info.get(key) 3055f9996aaSopenharmony_ci if part is None: 3065f9996aaSopenharmony_ci continue 3075f9996aaSopenharmony_ci for syscap in value: 3085f9996aaSopenharmony_ci if syscap not in all_syscap_list: 3095f9996aaSopenharmony_ci raise OHOSException( 3105f9996aaSopenharmony_ci "In config.json of part [{}],the syscap[{}] is incorrect, \ 3115f9996aaSopenharmony_ci please check the syscap name".format(key, syscap), "2008") 3125f9996aaSopenharmony_ci 3135f9996aaSopenharmony_ci for syscap in syscap_info_list: 3145f9996aaSopenharmony_ci remove_list = [] 3155f9996aaSopenharmony_ci if syscap['component'] not in self.required_parts_targets_list: 3165f9996aaSopenharmony_ci continue 3175f9996aaSopenharmony_ci if 'syscap' not in syscap or syscap['syscap'] is None \ 3185f9996aaSopenharmony_ci or len(syscap['syscap']) == 0 or syscap['syscap'] == [""]: 3195f9996aaSopenharmony_ci continue 3205f9996aaSopenharmony_ci for syscap_string in syscap['syscap']: 3215f9996aaSopenharmony_ci if syscap_string.startswith("SystemCapability.") is True: 3225f9996aaSopenharmony_ci target_syscap_init_str = "const." 3235f9996aaSopenharmony_ci syscap_name = syscap_string.split('=')[0].strip() 3245f9996aaSopenharmony_ci all_syscap_product = syscap_product_dict['syscap'] 3255f9996aaSopenharmony_ci if syscap_name in all_syscap_product and not all_syscap_product[syscap_name]: 3265f9996aaSopenharmony_ci remove_list.append(syscap_string) 3275f9996aaSopenharmony_ci continue 3285f9996aaSopenharmony_ci elif syscap_name in all_syscap_product and all_syscap_product[syscap_name]: 3295f9996aaSopenharmony_ci target_syscap_init_str += syscap_name + '=true\n' 3305f9996aaSopenharmony_ci else: 3315f9996aaSopenharmony_ci if syscap_string.endswith('true'): 3325f9996aaSopenharmony_ci target_syscap_init_str += syscap_name + '=true\n' 3335f9996aaSopenharmony_ci elif syscap_string.endswith('false'): 3345f9996aaSopenharmony_ci remove_list.append(syscap_string) 3355f9996aaSopenharmony_ci continue 3365f9996aaSopenharmony_ci else: 3375f9996aaSopenharmony_ci target_syscap_init_str += syscap_string + "=true\n" 3385f9996aaSopenharmony_ci if target_syscap_init_str not in target_syscap_for_init_list: 3395f9996aaSopenharmony_ci target_syscap_for_init_list.append( 3405f9996aaSopenharmony_ci target_syscap_init_str) 3415f9996aaSopenharmony_ci else: 3425f9996aaSopenharmony_ci raise OHOSException("""In bundle.json of part [{}], The syscap string [{}] is incorrect, 3435f9996aaSopenharmony_ci need start with \"SystemCapability.\"""".format(syscap['component'], syscap_string), "2009") 3445f9996aaSopenharmony_ci 3455f9996aaSopenharmony_ci for remove_str in remove_list: 3465f9996aaSopenharmony_ci syscap['syscap'].remove(remove_str) 3475f9996aaSopenharmony_ci for i in range(len(syscap['syscap'])): 3485f9996aaSopenharmony_ci if syscap['syscap'][i].endswith('true') or syscap['syscap'][i].endswith('false'): 3495f9996aaSopenharmony_ci syscap['syscap'][i] = syscap['syscap'][i].split('=')[ 3505f9996aaSopenharmony_ci 0].strip() 3515f9996aaSopenharmony_ci 3525f9996aaSopenharmony_ci syscap['syscap'].sort() 3535f9996aaSopenharmony_ci target_syscap_with_part_name_list.append(syscap) 3545f9996aaSopenharmony_ci target_syscap_list.extend(syscap['syscap']) 3555f9996aaSopenharmony_ci 3565f9996aaSopenharmony_ci # Generate SystemCapability.json & syscap.json & syscap.para 3575f9996aaSopenharmony_ci target_syscap_list.sort() 3585f9996aaSopenharmony_ci syscap_info_dict = read_json_file(os.path.join( 3595f9996aaSopenharmony_ci pre_syscap_info_path, "SystemCapability.json")) 3605f9996aaSopenharmony_ci syscap_info_dict.update({'syscap': {'os': target_syscap_list}}) 3615f9996aaSopenharmony_ci system_etc_path = os.path.join(system_path, "etc/") 3625f9996aaSopenharmony_ci if not os.path.exists(system_path): 3635f9996aaSopenharmony_ci os.mkdir(system_path) 3645f9996aaSopenharmony_ci if not os.path.exists(system_etc_path): 3655f9996aaSopenharmony_ci os.mkdir(system_etc_path) 3665f9996aaSopenharmony_ci syscap_info_json = os.path.join( 3675f9996aaSopenharmony_ci system_etc_path, "SystemCapability.json") 3685f9996aaSopenharmony_ci write_json_file(syscap_info_json, syscap_info_dict) 3695f9996aaSopenharmony_ci LogUtil.hb_info( 3705f9996aaSopenharmony_ci "generate syscap info file to '{}'".format(syscap_info_json), mode=self.config.log_mode) 3715f9996aaSopenharmony_ci target_syscap_with_part_name_list.sort( 3725f9996aaSopenharmony_ci key=lambda syscap: syscap['component']) 3735f9996aaSopenharmony_ci syscap_info_with_part_name_file = os.path.join( 3745f9996aaSopenharmony_ci system_etc_path, "syscap.json") 3755f9996aaSopenharmony_ci write_json_file(syscap_info_with_part_name_file, { 3765f9996aaSopenharmony_ci 'components': target_syscap_with_part_name_list}) 3775f9996aaSopenharmony_ci LogUtil.hb_info("generate syscap info with part name list to '{}'".format( 3785f9996aaSopenharmony_ci syscap_info_with_part_name_file), mode=self.config.log_mode) 3795f9996aaSopenharmony_ci if not os.path.exists(os.path.join(system_etc_path, "param/")): 3805f9996aaSopenharmony_ci os.mkdir(os.path.join(system_etc_path, "param/")) 3815f9996aaSopenharmony_ci target_syscap_for_init_file = os.path.join( 3825f9996aaSopenharmony_ci system_etc_path, "param/syscap.para") 3835f9996aaSopenharmony_ci with open(target_syscap_for_init_file, "w") as file: 3845f9996aaSopenharmony_ci file.writelines(sorted(target_syscap_for_init_list)) 3855f9996aaSopenharmony_ci LogUtil.hb_info("generate target syscap for init list to '{}'".format( 3865f9996aaSopenharmony_ci target_syscap_for_init_file), mode=self.config.log_mode) 3875f9996aaSopenharmony_ci 3885f9996aaSopenharmony_ci# get method 3895f9996aaSopenharmony_ci @throw_exception 3905f9996aaSopenharmony_ci def _get_build_platforms(self) -> list: 3915f9996aaSopenharmony_ci build_platforms = [] 3925f9996aaSopenharmony_ci if self.build_platform_name == 'all': 3935f9996aaSopenharmony_ci build_platforms = self._all_platforms 3945f9996aaSopenharmony_ci elif self.build_platform_name in self._all_platforms: 3955f9996aaSopenharmony_ci build_platforms = [self.build_platform_name] 3965f9996aaSopenharmony_ci else: 3975f9996aaSopenharmony_ci raise OHOSException( 3985f9996aaSopenharmony_ci "The target_platform is incorrect, only allows [{}].".format( 3995f9996aaSopenharmony_ci ', '.join(self._all_platforms)), "2010") 4005f9996aaSopenharmony_ci return build_platforms 4015f9996aaSopenharmony_ci 4025f9996aaSopenharmony_ci '''Description: output infos for testfwk into a json file. \ 4035f9996aaSopenharmony_ci (/out/${product_name}/build_configs/infos_for_testfwk.json) 4045f9996aaSopenharmony_ci @parameter:none 4055f9996aaSopenharmony_ci @return :none 4065f9996aaSopenharmony_ci ''' 4075f9996aaSopenharmony_ci 4085f9996aaSopenharmony_ci def _generate_infos_for_testfwk(self): 4095f9996aaSopenharmony_ci infos_for_testfwk_file = os.path.join(self.config_output_dir, 4105f9996aaSopenharmony_ci "infos_for_testfwk.json") 4115f9996aaSopenharmony_ci parts_info = self.parts_config_info.get('parts_info') 4125f9996aaSopenharmony_ci parts_info_dict = {} 4135f9996aaSopenharmony_ci for _part_name, _parts in parts_info.items(): 4145f9996aaSopenharmony_ci for _info in _parts: 4155f9996aaSopenharmony_ci parts_info_dict[_info.get('part_name')] = _info 4165f9996aaSopenharmony_ci _output_infos = {} 4175f9996aaSopenharmony_ci for _platform, _parts in self.target_platform_parts.items(): 4185f9996aaSopenharmony_ci result = self._output_infos_by_platform(_parts, parts_info_dict) 4195f9996aaSopenharmony_ci _output_infos[_platform] = result 4205f9996aaSopenharmony_ci write_json_file(infos_for_testfwk_file, 4215f9996aaSopenharmony_ci _output_infos, check_changes=True) 4225f9996aaSopenharmony_ci LogUtil.hb_info("generate infos for testfwk to '{}'".format( 4235f9996aaSopenharmony_ci infos_for_testfwk_file), mode=self.config.log_mode) 4245f9996aaSopenharmony_ci 4255f9996aaSopenharmony_ci '''Description: output all target platform parts into a json file \ 4265f9996aaSopenharmony_ci (/out/${product_name}/build_configs/target_platforms_parts.json) 4275f9996aaSopenharmony_ci @parameter:none 4285f9996aaSopenharmony_ci @return :none 4295f9996aaSopenharmony_ci ''' 4305f9996aaSopenharmony_ci 4315f9996aaSopenharmony_ci def _generate_target_platform_parts(self): 4325f9996aaSopenharmony_ci target_platform_parts_file = os.path.join(self.config_output_dir, 4335f9996aaSopenharmony_ci "target_platforms_parts.json") 4345f9996aaSopenharmony_ci write_json_file(target_platform_parts_file, 4355f9996aaSopenharmony_ci self.target_platform_parts, 4365f9996aaSopenharmony_ci check_changes=True) 4375f9996aaSopenharmony_ci LogUtil.hb_info("generate target platform parts to '{}'".format( 4385f9996aaSopenharmony_ci target_platform_parts_file), mode=self.config.log_mode) 4395f9996aaSopenharmony_ci 4405f9996aaSopenharmony_ci '''Description: Generate parts differences in different platforms, using phone as base. \ 4415f9996aaSopenharmony_ci (/out/${product_name}/build_configs/parts_different_info.json) 4425f9996aaSopenharmony_ci @parameter: none 4435f9996aaSopenharmony_ci @return :none 4445f9996aaSopenharmony_ci ''' 4455f9996aaSopenharmony_ci 4465f9996aaSopenharmony_ci def _generate_part_different_info(self): 4475f9996aaSopenharmony_ci parts_different_info = self._get_parts_by_platform() 4485f9996aaSopenharmony_ci parts_different_info_file = os.path.join(self.config_output_dir, 4495f9996aaSopenharmony_ci "parts_different_info.json") 4505f9996aaSopenharmony_ci write_json_file(parts_different_info_file, 4515f9996aaSopenharmony_ci parts_different_info, 4525f9996aaSopenharmony_ci check_changes=True) 4535f9996aaSopenharmony_ci LogUtil.hb_info("generate part different info to '{}'".format( 4545f9996aaSopenharmony_ci parts_different_info_file), mode=self.config.log_mode) 4555f9996aaSopenharmony_ci 4565f9996aaSopenharmony_ci '''Description: output platforms list into a gni file. \ 4575f9996aaSopenharmony_ci (/out/${product_name}/build_configs/platforms_list.gni) 4585f9996aaSopenharmony_ci @parameter: none 4595f9996aaSopenharmony_ci @return: none 4605f9996aaSopenharmony_ci ''' 4615f9996aaSopenharmony_ci 4625f9996aaSopenharmony_ci def _generate_platforms_list(self): 4635f9996aaSopenharmony_ci platforms_list_gni_file = os.path.join(self.config_output_dir, 4645f9996aaSopenharmony_ci "platforms_list.gni") 4655f9996aaSopenharmony_ci _platforms = set(self.build_platforms) 4665f9996aaSopenharmony_ci _gni_file_content = ['target_platform_list = [', ' "{}"'.format('",\n "'.join(_platforms)), ']', 4675f9996aaSopenharmony_ci 'kits_platform_list = [', ' "{}",'.format('",\n "'.join(_platforms))] 4685f9996aaSopenharmony_ci if 'phone' not in self.build_platforms: 4695f9996aaSopenharmony_ci _gni_file_content.append(' "phone"') 4705f9996aaSopenharmony_ci _gni_file_content.append(']') 4715f9996aaSopenharmony_ci write_file(platforms_list_gni_file, '\n'.join(_gni_file_content)) 4725f9996aaSopenharmony_ci LogUtil.hb_info("generate platforms list to '{}'".format( 4735f9996aaSopenharmony_ci platforms_list_gni_file), mode=self.config.log_mode) 4745f9996aaSopenharmony_ci 4755f9996aaSopenharmony_ci '''Description: output auto install part into a json file. \ 4765f9996aaSopenharmony_ci (/out/${product_name}/build_configs/auto_install_parts.json) 4775f9996aaSopenharmony_ci @parameter: none 4785f9996aaSopenharmony_ci @return: none 4795f9996aaSopenharmony_ci ''' 4805f9996aaSopenharmony_ci 4815f9996aaSopenharmony_ci def _generate_auto_install_part(self): 4825f9996aaSopenharmony_ci parts_path_info = self.parts_config_info.get("parts_path_info") 4835f9996aaSopenharmony_ci auto_install_part_list = [] 4845f9996aaSopenharmony_ci for part, path in parts_path_info.items(): 4855f9996aaSopenharmony_ci if str(path).startswith("drivers/interface") or \ 4865f9996aaSopenharmony_ci str(path).startswith("third_party"): 4875f9996aaSopenharmony_ci auto_install_part_list.append(part) 4885f9996aaSopenharmony_ci auto_install_list_file = os.path.join( 4895f9996aaSopenharmony_ci self.config_output_dir, "auto_install_parts.json") 4905f9996aaSopenharmony_ci write_json_file(auto_install_list_file, auto_install_part_list) 4915f9996aaSopenharmony_ci LogUtil.hb_info("generate auto install part to '{}'".format( 4925f9996aaSopenharmony_ci auto_install_list_file), mode=self.config.log_mode) 4935f9996aaSopenharmony_ci 4945f9996aaSopenharmony_ci '''Description: output src flag into a json file. \ 4955f9996aaSopenharmony_ci (/out/${product_name}/build_configs/parts_src_flag.json) 4965f9996aaSopenharmony_ci @parameter: none 4975f9996aaSopenharmony_ci @return :none 4985f9996aaSopenharmony_ci ''' 4995f9996aaSopenharmony_ci 5005f9996aaSopenharmony_ci def _generate_src_flag(self): 5015f9996aaSopenharmony_ci parts_src_flag_file = os.path.join(self.config_output_dir, 5025f9996aaSopenharmony_ci "parts_src_flag.json") 5035f9996aaSopenharmony_ci write_json_file(parts_src_flag_file, 5045f9996aaSopenharmony_ci self._get_parts_src_list(), 5055f9996aaSopenharmony_ci check_changes=True) 5065f9996aaSopenharmony_ci LogUtil.hb_info( 5075f9996aaSopenharmony_ci "generated parts src flag to '{}/subsystem_info/parts_src_flag.json'".format( 5085f9996aaSopenharmony_ci self.config_output_dir), mode=self.config.log_mode) 5095f9996aaSopenharmony_ci 5105f9996aaSopenharmony_ci '''Description: output build target list into a json file.\ 5115f9996aaSopenharmony_ci (/out/${product_name}/build_configs/required_parts_targets_list.json) 5125f9996aaSopenharmony_ci @parameter: none 5135f9996aaSopenharmony_ci @return :none 5145f9996aaSopenharmony_ci ''' 5155f9996aaSopenharmony_ci 5165f9996aaSopenharmony_ci def _generate_required_parts_targets_list(self): 5175f9996aaSopenharmony_ci build_targets_list_file = os.path.join(self.config_output_dir, 5185f9996aaSopenharmony_ci "required_parts_targets_list.json") 5195f9996aaSopenharmony_ci write_json_file(build_targets_list_file, 5205f9996aaSopenharmony_ci list(self.required_parts_targets.values())) 5215f9996aaSopenharmony_ci LogUtil.hb_info("generate build targets list file to '{}'".format( 5225f9996aaSopenharmony_ci build_targets_list_file), mode=self.config.log_mode) 5235f9996aaSopenharmony_ci 5245f9996aaSopenharmony_ci '''Description: output build target info into a json file. \ 5255f9996aaSopenharmony_ci (/out/${product_name}/build_configs/required_parts_targets.json) 5265f9996aaSopenharmony_ci @parameter: none 5275f9996aaSopenharmony_ci @return: none 5285f9996aaSopenharmony_ci ''' 5295f9996aaSopenharmony_ci 5305f9996aaSopenharmony_ci def _generate_required_parts_targets(self): 5315f9996aaSopenharmony_ci build_targets_info_file = os.path.join(self.config_output_dir, 5325f9996aaSopenharmony_ci "required_parts_targets.json") 5335f9996aaSopenharmony_ci write_json_file(build_targets_info_file, self.required_parts_targets) 5345f9996aaSopenharmony_ci LogUtil.hb_info("generate required parts targets to '{}'".format( 5355f9996aaSopenharmony_ci build_targets_info_file), mode=self.config.log_mode) 5365f9996aaSopenharmony_ci 5375f9996aaSopenharmony_ci '''Description: output platforms part by src into a json file. \ 5385f9996aaSopenharmony_ci (/out/${product_name}/build_configs/platforms_parts_by_src.json) 5395f9996aaSopenharmony_ci @parameter: none 5405f9996aaSopenharmony_ci @return :none 5415f9996aaSopenharmony_ci ''' 5425f9996aaSopenharmony_ci 5435f9996aaSopenharmony_ci def _generate_platforms_part_by_src(self): 5445f9996aaSopenharmony_ci platforms_parts_by_src = self._get_platforms_parts() 5455f9996aaSopenharmony_ci platforms_parts_by_src_file = os.path.join(self.source_root_dir, 5465f9996aaSopenharmony_ci self.config_output_relpath, 5475f9996aaSopenharmony_ci "platforms_parts_by_src.json") 5485f9996aaSopenharmony_ci write_json_file(platforms_parts_by_src_file, 5495f9996aaSopenharmony_ci platforms_parts_by_src, 5505f9996aaSopenharmony_ci check_changes=True) 5515f9996aaSopenharmony_ci LogUtil.hb_info("generated platforms parts by src to '{}'".format( 5525f9996aaSopenharmony_ci platforms_parts_by_src_file), mode=self.config.log_mode) 5535f9996aaSopenharmony_ci 5545f9996aaSopenharmony_ci '''Description: output system configs info into 4 files:[ 5555f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/parts_list.gni), 5565f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/inner_kits_list.gni), 5575f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/system_kits_list.gni), 5585f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/parts_test_list.gni), 5595f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/BUILD.gn)] 5605f9996aaSopenharmony_ci @parameter: none 5615f9996aaSopenharmony_ci @return :none 5625f9996aaSopenharmony_ci ''' 5635f9996aaSopenharmony_ci 5645f9996aaSopenharmony_ci def _generate_target_gn(self): 5655f9996aaSopenharmony_ci generate_targets_gn.gen_targets_gn(self.required_parts_targets, 5665f9996aaSopenharmony_ci self.config_output_dir) 5675f9996aaSopenharmony_ci 5685f9996aaSopenharmony_ci '''Description: output phony targets build file. \ 5695f9996aaSopenharmony_ci (/out/${product_name}/build_configs/phony_target/BUILD.gn) 5705f9996aaSopenharmony_ci @parameter: none 5715f9996aaSopenharmony_ci @return :none 5725f9996aaSopenharmony_ci ''' 5735f9996aaSopenharmony_ci 5745f9996aaSopenharmony_ci def _generate_phony_targets_build_file(self): 5755f9996aaSopenharmony_ci generate_targets_gn.gen_phony_targets(self.required_phony_targets, 5765f9996aaSopenharmony_ci self.config_output_dir) 5775f9996aaSopenharmony_ci 5785f9996aaSopenharmony_ci '''Description: output system configs info into 2 files:[ 5795f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/${platform}-stub/BUILG.gn), 5805f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/${platform}-stub/zframework_stub_exists.gni)] 5815f9996aaSopenharmony_ci @parameter: none 5825f9996aaSopenharmony_ci @return :none 5835f9996aaSopenharmony_ci ''' 5845f9996aaSopenharmony_ci 5855f9996aaSopenharmony_ci def _generate_stub_targets(self): 5865f9996aaSopenharmony_ci generate_targets_gn.gen_stub_targets( 5875f9996aaSopenharmony_ci self.parts_config_info.get('parts_kits_info'), 5885f9996aaSopenharmony_ci self.target_platform_stubs, 5895f9996aaSopenharmony_ci self.config_output_dir) 5905f9996aaSopenharmony_ci 5915f9996aaSopenharmony_ci '''Description: output system capabilities into a json file. \ 5925f9996aaSopenharmony_ci (/out/${product_name}/build_configs/${platform}_system_capabilities.json) 5935f9996aaSopenharmony_ci @parameter: none 5945f9996aaSopenharmony_ci @return :none 5955f9996aaSopenharmony_ci ''' 5965f9996aaSopenharmony_ci 5975f9996aaSopenharmony_ci def _generate_system_capabilities(self): 5985f9996aaSopenharmony_ci for platform in self.build_platforms: 5995f9996aaSopenharmony_ci platform_parts = self.target_platform_parts.get(platform) 6005f9996aaSopenharmony_ci platform_capabilities = [] 6015f9996aaSopenharmony_ci for _, origin in platform_parts.items(): 6025f9996aaSopenharmony_ci # parts_info.get() might be None if the part is a binary package 6035f9996aaSopenharmony_ci all_parts_variants = self.parts_info.get(origin) 6045f9996aaSopenharmony_ci if all_parts_variants is None: 6055f9996aaSopenharmony_ci continue 6065f9996aaSopenharmony_ci part = all_parts_variants[0] 6075f9996aaSopenharmony_ci if part.get('system_capabilities'): 6085f9996aaSopenharmony_ci entry = part.get('system_capabilities') 6095f9996aaSopenharmony_ci if len(entry) > 0: 6105f9996aaSopenharmony_ci platform_capabilities.extend(entry) 6115f9996aaSopenharmony_ci platform_part_json_file = os.path.join( 6125f9996aaSopenharmony_ci self.config_output_dir, "{0}_system_capabilities.json".format(platform)) 6135f9996aaSopenharmony_ci write_json_file(platform_part_json_file, 6145f9996aaSopenharmony_ci sorted(platform_capabilities), 6155f9996aaSopenharmony_ci check_changes=True) 6165f9996aaSopenharmony_ci LogUtil.hb_info( 6175f9996aaSopenharmony_ci "generated system capabilities to '{}/{}_system_capabilities.json'".format( 6185f9996aaSopenharmony_ci self.config_output_dir, platform), mode=self.config.log_mode) 6195f9996aaSopenharmony_ci 6205f9996aaSopenharmony_ci '''Description: output system configs info into three json files:[ 6215f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/subsystem_build_config.json), 6225f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/src_subsystem_info.json), 6235f9996aaSopenharmony_ci (/out/${product_name}/build_configs/subsystem_info/no_src_subsystem_info.json)] 6245f9996aaSopenharmony_ci @parameter: none 6255f9996aaSopenharmony_ci @return :none 6265f9996aaSopenharmony_ci ''' 6275f9996aaSopenharmony_ci 6285f9996aaSopenharmony_ci def _generate_subsystem_configs(self): 6295f9996aaSopenharmony_ci 6305f9996aaSopenharmony_ci # The function has been implemented in module util/loader/subsystem_info.py 6315f9996aaSopenharmony_ci LogUtil.hb_info( 6325f9996aaSopenharmony_ci "generated subsystem build config to '{}/subsystem_info/subsystem_build_config.json'".format( 6335f9996aaSopenharmony_ci self.config_output_dir), mode=self.config.log_mode) 6345f9996aaSopenharmony_ci LogUtil.hb_info( 6355f9996aaSopenharmony_ci "generated src subsystem info to '{}/subsystem_info/src_subsystem_info.json'".format( 6365f9996aaSopenharmony_ci self.config_output_dir), mode=self.config.log_mode) 6375f9996aaSopenharmony_ci LogUtil.hb_info( 6385f9996aaSopenharmony_ci "generated no src subsystem info to '{}/subsystem_info/no_src_subsystem_info.json'".format( 6395f9996aaSopenharmony_ci self.config_output_dir), mode=self.config.log_mode) 6405f9996aaSopenharmony_ci 6415f9996aaSopenharmony_ci def _get_parts_by_platform(self) -> dict: 6425f9996aaSopenharmony_ci parts_info = {} 6435f9996aaSopenharmony_ci if 'phone' in self.target_platform_parts: 6445f9996aaSopenharmony_ci phone_parts_list = self.target_platform_parts.get('phone').keys() 6455f9996aaSopenharmony_ci else: 6465f9996aaSopenharmony_ci phone_parts_list = [] 6475f9996aaSopenharmony_ci for _platform, _parts_info in self.target_platform_parts.items(): 6485f9996aaSopenharmony_ci base_parts_list = [] 6495f9996aaSopenharmony_ci curr_parts_list = [] 6505f9996aaSopenharmony_ci for _real_name, _original_name in _parts_info.items(): 6515f9996aaSopenharmony_ci if _real_name in phone_parts_list: 6525f9996aaSopenharmony_ci base_parts_list.append(_real_name) 6535f9996aaSopenharmony_ci elif _original_name in phone_parts_list: 6545f9996aaSopenharmony_ci base_parts_list.append(_real_name) 6555f9996aaSopenharmony_ci else: 6565f9996aaSopenharmony_ci curr_parts_list.append(_real_name) 6575f9996aaSopenharmony_ci result_data = { 6585f9996aaSopenharmony_ci "base_parts_list": base_parts_list, 6595f9996aaSopenharmony_ci "curr_parts_list": curr_parts_list 6605f9996aaSopenharmony_ci } 6615f9996aaSopenharmony_ci parts_info[_platform] = result_data 6625f9996aaSopenharmony_ci return parts_info 6635f9996aaSopenharmony_ci 6645f9996aaSopenharmony_ci def _get_platforms_all_parts(self) -> dict: 6655f9996aaSopenharmony_ci _dist_parts_variants = self._load_component_dist() 6665f9996aaSopenharmony_ci target_platform_parts = {} 6675f9996aaSopenharmony_ci all_parts = self._platforms_info.get('all_parts') 6685f9996aaSopenharmony_ci parts_variants = self.parts_config_info.get('parts_variants') 6695f9996aaSopenharmony_ci for _platform, _parts in all_parts.items(): 6705f9996aaSopenharmony_ci if _platform not in self.build_platforms: 6715f9996aaSopenharmony_ci continue 6725f9996aaSopenharmony_ci part_name_info = {} 6735f9996aaSopenharmony_ci for part_def in _parts: 6745f9996aaSopenharmony_ci real_name, original_name = self._get_real_part_name( 6755f9996aaSopenharmony_ci part_def, _platform, parts_variants) 6765f9996aaSopenharmony_ci if real_name is None: 6775f9996aaSopenharmony_ci # find this from component_dist 6785f9996aaSopenharmony_ci real_name, original_name = self._get_real_part_name( 6795f9996aaSopenharmony_ci part_def, _platform, _dist_parts_variants) 6805f9996aaSopenharmony_ci if real_name is None: 6815f9996aaSopenharmony_ci continue 6825f9996aaSopenharmony_ci part_name_info[real_name] = original_name 6835f9996aaSopenharmony_ci target_platform_parts[_platform] = part_name_info 6845f9996aaSopenharmony_ci return target_platform_parts 6855f9996aaSopenharmony_ci 6865f9996aaSopenharmony_ci def _get_platforms_all_stubs(self) -> dict: 6875f9996aaSopenharmony_ci _dist_parts_variants = self._load_component_dist() 6885f9996aaSopenharmony_ci platform_stubs = {} 6895f9996aaSopenharmony_ci all_stubs = self._platforms_info.get('all_stubs') 6905f9996aaSopenharmony_ci parts_variants = self.parts_config_info.get('parts_variants') 6915f9996aaSopenharmony_ci for _platform, _part_names in all_stubs.items(): 6925f9996aaSopenharmony_ci if _platform not in self.build_platforms: 6935f9996aaSopenharmony_ci continue 6945f9996aaSopenharmony_ci stub_parts_from_src = [] 6955f9996aaSopenharmony_ci stub_parts_from_dist = [] 6965f9996aaSopenharmony_ci for part_name in _part_names: 6975f9996aaSopenharmony_ci real_name, original_name = self._get_real_part_name( 6985f9996aaSopenharmony_ci part_name, _platform, parts_variants) 6995f9996aaSopenharmony_ci # real_name=None means part_name doesn't exist in source tree, 7005f9996aaSopenharmony_ci # use binary in component_dist then. 7015f9996aaSopenharmony_ci if real_name is None: 7025f9996aaSopenharmony_ci # find this from component_dist 7035f9996aaSopenharmony_ci real_name, original_name = self._get_real_part_name( 7045f9996aaSopenharmony_ci part_name, _platform, _dist_parts_variants) 7055f9996aaSopenharmony_ci if real_name is None: 7065f9996aaSopenharmony_ci continue 7075f9996aaSopenharmony_ci else: 7085f9996aaSopenharmony_ci stub_sources = os.path.join( 7095f9996aaSopenharmony_ci self.source_root_dir, 7105f9996aaSopenharmony_ci "component_dist/{}-{}/api_stubs/{}/stubs_sources_list.txt" # noqa: E501 7115f9996aaSopenharmony_ci .format(self.target_os, self.target_cpu, real_name)) 7125f9996aaSopenharmony_ci stub_parts_from_dist.append( 7135f9996aaSopenharmony_ci '"{}"'.format(stub_sources)) 7145f9996aaSopenharmony_ci else: 7155f9996aaSopenharmony_ci stub_parts_from_src.append(real_name) 7165f9996aaSopenharmony_ci platform_stubs[_platform] = { 7175f9996aaSopenharmony_ci "src": stub_parts_from_src, 7185f9996aaSopenharmony_ci "dist": stub_parts_from_dist, 7195f9996aaSopenharmony_ci } 7205f9996aaSopenharmony_ci return platform_stubs 7215f9996aaSopenharmony_ci 7225f9996aaSopenharmony_ci def _get_platforms_parts(self) -> dict: 7235f9996aaSopenharmony_ci platforms_parts = {} 7245f9996aaSopenharmony_ci src_parts_targets = self.parts_targets 7255f9996aaSopenharmony_ci src_all_parts = src_parts_targets.keys() 7265f9996aaSopenharmony_ci for _platform, _all_parts in self.target_platform_parts.items(): 7275f9996aaSopenharmony_ci src_parts_list = [] 7285f9996aaSopenharmony_ci no_src_parts_list = [] 7295f9996aaSopenharmony_ci for _part in _all_parts.keys(): 7305f9996aaSopenharmony_ci if _part in src_all_parts: 7315f9996aaSopenharmony_ci src_parts_list.append(_part) 7325f9996aaSopenharmony_ci else: 7335f9996aaSopenharmony_ci no_src_parts_list.append(_part) 7345f9996aaSopenharmony_ci _data = { 7355f9996aaSopenharmony_ci 'src_parts': src_parts_list, 7365f9996aaSopenharmony_ci 'no_src_parts': no_src_parts_list 7375f9996aaSopenharmony_ci } 7385f9996aaSopenharmony_ci platforms_parts[_platform] = _data 7395f9996aaSopenharmony_ci return platforms_parts 7405f9996aaSopenharmony_ci 7415f9996aaSopenharmony_ci def _get_parts_src_list(self) -> list: 7425f9996aaSopenharmony_ci parts_name_map = {} 7435f9996aaSopenharmony_ci for _list in self.parts_info.values(): 7445f9996aaSopenharmony_ci for _info in _list: 7455f9996aaSopenharmony_ci parts_name_map[_info.get('part_name')] = _info.get( 7465f9996aaSopenharmony_ci 'origin_part_name') 7475f9996aaSopenharmony_ci _src_set = set() 7485f9996aaSopenharmony_ci for _name in self.required_parts_targets.keys(): 7495f9996aaSopenharmony_ci _origin_name = parts_name_map.get(_name) 7505f9996aaSopenharmony_ci if _origin_name is None: 7515f9996aaSopenharmony_ci continue 7525f9996aaSopenharmony_ci _src_set.add(_origin_name) 7535f9996aaSopenharmony_ci return list(_src_set) 7545f9996aaSopenharmony_ci 7555f9996aaSopenharmony_ci def _get_required_build_targets(self) -> dict: 7565f9996aaSopenharmony_ci required_build_targets = {} 7575f9996aaSopenharmony_ci for _p_name, _info in self.parts_targets.items(): 7585f9996aaSopenharmony_ci if _p_name not in self.required_parts_targets_list: 7595f9996aaSopenharmony_ci continue 7605f9996aaSopenharmony_ci required_build_targets[_p_name] = _info 7615f9996aaSopenharmony_ci return required_build_targets 7625f9996aaSopenharmony_ci 7635f9996aaSopenharmony_ci def _get_required_phony_targets(self) -> dict: 7645f9996aaSopenharmony_ci required_build_targets = {} 7655f9996aaSopenharmony_ci for _p_name, _info in self.phony_targets.items(): 7665f9996aaSopenharmony_ci if _p_name not in self.required_parts_targets_list: 7675f9996aaSopenharmony_ci continue 7685f9996aaSopenharmony_ci required_build_targets[_p_name] = _info 7695f9996aaSopenharmony_ci return required_build_targets 7705f9996aaSopenharmony_ci 7715f9996aaSopenharmony_ci def _get_required_build_parts_list(self) -> list: 7725f9996aaSopenharmony_ci parts_set = set() 7735f9996aaSopenharmony_ci for _parts_list in self.target_platform_parts.values(): 7745f9996aaSopenharmony_ci parts_set.update(_parts_list) 7755f9996aaSopenharmony_ci return list(parts_set) 7765f9996aaSopenharmony_ci 7775f9996aaSopenharmony_ci# util method 7785f9996aaSopenharmony_ci 7795f9996aaSopenharmony_ci def _load_component_dist(self) -> dict: 7805f9996aaSopenharmony_ci _parts_variants_info = {} 7815f9996aaSopenharmony_ci _dir = "component_dist/{}-{}/packages_to_install".format( 7825f9996aaSopenharmony_ci self.target_os, self.target_cpu) 7835f9996aaSopenharmony_ci _file_name = "dist_parts_info.json" 7845f9996aaSopenharmony_ci _dist_parts_info_file = os.path.join( 7855f9996aaSopenharmony_ci self.source_root_dir, _dir, _file_name) 7865f9996aaSopenharmony_ci if not os.path.exists(_dist_parts_info_file): 7875f9996aaSopenharmony_ci # If the file does not exist, do nothing and return 7885f9996aaSopenharmony_ci return _parts_variants_info 7895f9996aaSopenharmony_ci _parts_info = read_json_file(_dist_parts_info_file) 7905f9996aaSopenharmony_ci if _parts_info is None: 7915f9996aaSopenharmony_ci raise Exception("read file '{}' failed.".format( 7925f9996aaSopenharmony_ci _dist_parts_info_file)) 7935f9996aaSopenharmony_ci for _part_info in _parts_info: 7945f9996aaSopenharmony_ci origin_part_name = _part_info.get('origin_part_name') 7955f9996aaSopenharmony_ci if origin_part_name in _parts_variants_info: 7965f9996aaSopenharmony_ci variants = _parts_variants_info.get(origin_part_name) 7975f9996aaSopenharmony_ci else: 7985f9996aaSopenharmony_ci variants = [] 7995f9996aaSopenharmony_ci _variant_name = _part_info.get('variant_name') 8005f9996aaSopenharmony_ci variants.append(_variant_name) 8015f9996aaSopenharmony_ci _parts_variants_info[origin_part_name] = variants 8025f9996aaSopenharmony_ci return _parts_variants_info 8035f9996aaSopenharmony_ci 8045f9996aaSopenharmony_ci def _get_real_part_name(self, original_part_name: str, current_platform: str, parts_variants: dict): 8055f9996aaSopenharmony_ci part_info = parts_variants.get(original_part_name) 8065f9996aaSopenharmony_ci if part_info is None: 8075f9996aaSopenharmony_ci return None, None 8085f9996aaSopenharmony_ci if current_platform in part_info and current_platform != 'phone': 8095f9996aaSopenharmony_ci real_name = '{}_{}'.format(original_part_name, current_platform) 8105f9996aaSopenharmony_ci else: 8115f9996aaSopenharmony_ci real_name = original_part_name 8125f9996aaSopenharmony_ci return real_name, original_part_name 8135f9996aaSopenharmony_ci 8145f9996aaSopenharmony_ci '''Description: called by _out_infos_for_testfwk, output information by platform 8155f9996aaSopenharmony_ci @parameter:none 8165f9996aaSopenharmony_ci @return :none 8175f9996aaSopenharmony_ci ''' 8185f9996aaSopenharmony_ci 8195f9996aaSopenharmony_ci def _output_infos_by_platform(self, part_name_infos: dict, parts_info_dict: dict): 8205f9996aaSopenharmony_ci required_parts = {} 8215f9996aaSopenharmony_ci subsystem_infos = {} 8225f9996aaSopenharmony_ci for part_name, origin_part_name in part_name_infos.items(): 8235f9996aaSopenharmony_ci part_info = parts_info_dict.get(part_name) 8245f9996aaSopenharmony_ci if part_info is None: 8255f9996aaSopenharmony_ci continue 8265f9996aaSopenharmony_ci if origin_part_name != part_info.get('origin_part_name'): 8275f9996aaSopenharmony_ci raise Exception("part configuration is incorrect.") 8285f9996aaSopenharmony_ci required_parts[origin_part_name] = part_info 8295f9996aaSopenharmony_ci _subsystem_name = part_info.get('subsystem_name') 8305f9996aaSopenharmony_ci if _subsystem_name in subsystem_infos: 8315f9996aaSopenharmony_ci p_list = subsystem_infos.get(_subsystem_name) 8325f9996aaSopenharmony_ci else: 8335f9996aaSopenharmony_ci p_list = [] 8345f9996aaSopenharmony_ci p_list.append(origin_part_name) 8355f9996aaSopenharmony_ci subsystem_infos[_subsystem_name] = p_list 8365f9996aaSopenharmony_ci result = {} 8375f9996aaSopenharmony_ci result['subsystem_infos'] = subsystem_infos 8385f9996aaSopenharmony_ci result['part_infos'] = required_parts 8395f9996aaSopenharmony_ci return result 8405f9996aaSopenharmony_ci 8415f9996aaSopenharmony_ci def _execute_loader_args_display(self): 8425f9996aaSopenharmony_ci LogUtil.hb_info('Loading configuration file...') 8435f9996aaSopenharmony_ci args = [] 8445f9996aaSopenharmony_ci args.append('platforms_config_file="{}"'.format( 8455f9996aaSopenharmony_ci self.platforms_config_file)) 8465f9996aaSopenharmony_ci args.append('subsystem_config_file="{}"'.format( 8475f9996aaSopenharmony_ci self.subsystem_config_file)) 8485f9996aaSopenharmony_ci args.append('example_subsystem_file="{}"'.format( 8495f9996aaSopenharmony_ci self.example_subsystem_file)) 8505f9996aaSopenharmony_ci args.append('exclusion_modules_config_file="{}"'.format( 8515f9996aaSopenharmony_ci self.exclusion_modules_config_file)) 8525f9996aaSopenharmony_ci args.append('source_root_dir="{}"'.format(self.source_root_dir)) 8535f9996aaSopenharmony_ci args.append('gn_root_out_dir="{}"'.format(self.gn_root_out_dir)) 8545f9996aaSopenharmony_ci args.append('build_platform_name={}'.format(self.build_platform_name)) 8555f9996aaSopenharmony_ci args.append('build_xts={}'.format(self.build_xts)) 8565f9996aaSopenharmony_ci args.append('load_test_config={}'.format(self.load_test_config)) 8575f9996aaSopenharmony_ci args.append('target_os={}'.format(self.target_os)) 8585f9996aaSopenharmony_ci args.append('target_cpu={}'.format(self.target_cpu)) 8595f9996aaSopenharmony_ci args.append('os_level={}'.format(self.os_level)) 8605f9996aaSopenharmony_ci args.append('ignore_api_check={}'.format(self.ignore_api_check)) 8615f9996aaSopenharmony_ci args.append('scalable_build={}'.format(self.scalable_build)) 8625f9996aaSopenharmony_ci args.append('skip_partlist_check={}'.format(self.skip_partlist_check)) 8635f9996aaSopenharmony_ci LogUtil.write_log(self.config.log_path, 8645f9996aaSopenharmony_ci 'loader args:{}'.format(args), 'info') 8655f9996aaSopenharmony_ci 8665f9996aaSopenharmony_ci def _override_components(self): 8675f9996aaSopenharmony_ci '''Description: Check whether there are components that need to be replaced, and if so, 8685f9996aaSopenharmony_ci replace the component configuration file bundle.json in subsystem_info and update 8695f9996aaSopenharmony_ci the component list generated by the preloader. 8705f9996aaSopenharmony_ci @parameter:none 8715f9996aaSopenharmony_ci @return :overrided_components 8725f9996aaSopenharmony_ci ''' 8735f9996aaSopenharmony_ci parts_file = self.platforms_config_file.replace( 8745f9996aaSopenharmony_ci "platforms.build", "parts.json") 8755f9996aaSopenharmony_ci all_parts = read_json_file(parts_file) 8765f9996aaSopenharmony_ci if "parts" not in all_parts: 8775f9996aaSopenharmony_ci LogUtil.hb_warning("{} does not contain parts!".format(parts_file)) 8785f9996aaSopenharmony_ci return {} 8795f9996aaSopenharmony_ci overrided = False 8805f9996aaSopenharmony_ci overrided_components = {} 8815f9996aaSopenharmony_ci all_parts = all_parts["parts"] 8825f9996aaSopenharmony_ci component_override_map = {} 8835f9996aaSopenharmony_ci all_component_override_map = {} 8845f9996aaSopenharmony_ci for subsystem_name, build_config_info in self._subsystem_info.items(): 8855f9996aaSopenharmony_ci if "build_files" not in build_config_info: 8865f9996aaSopenharmony_ci continue 8875f9996aaSopenharmony_ci 8885f9996aaSopenharmony_ci # scan all bundle.json or ohos.build files with named groups 8895f9996aaSopenharmony_ci for build_file in build_config_info["build_files"]: 8905f9996aaSopenharmony_ci 8915f9996aaSopenharmony_ci # ohos.build does not support overrided components 8925f9996aaSopenharmony_ci if not build_file.endswith('bundle.json'): 8935f9996aaSopenharmony_ci continue 8945f9996aaSopenharmony_ci 8955f9996aaSopenharmony_ci # Only device or vendor components can do named groups extensions 8965f9996aaSopenharmony_ci if (not build_file.startswith(self.source_root_dir + 'device/')) \ 8975f9996aaSopenharmony_ci and (not build_file.startswith(self.source_root_dir + 'vendor/')): 8985f9996aaSopenharmony_ci continue 8995f9996aaSopenharmony_ci 9005f9996aaSopenharmony_ci # "subsystem", "name" and "override" is required 9015f9996aaSopenharmony_ci component = read_json_file(build_file).get("component") 9025f9996aaSopenharmony_ci 9035f9996aaSopenharmony_ci if (not component) or (not all(key in component for key in ("subsystem", "name", "override"))): 9045f9996aaSopenharmony_ci continue 9055f9996aaSopenharmony_ci 9065f9996aaSopenharmony_ci full_part_name = f"{component.get('subsystem')}:{component.get('name')}" 9075f9996aaSopenharmony_ci if full_part_name not in all_parts: 9085f9996aaSopenharmony_ci LogUtil.hb_warning("{} was not configured for this product: {}".format( 9095f9996aaSopenharmony_ci build_file, full_part_name)) 9105f9996aaSopenharmony_ci continue 9115f9996aaSopenharmony_ci 9125f9996aaSopenharmony_ci if self._override_one_component(self._subsystem_info, component, build_file, all_parts, overrided_components, component_override_map): 9135f9996aaSopenharmony_ci overrided = True 9145f9996aaSopenharmony_ci 9155f9996aaSopenharmony_ci if overrided: 9165f9996aaSopenharmony_ci # Update parts.json and parts_config.json generated by preloader 9175f9996aaSopenharmony_ci write_json_file(parts_file, {"parts": all_parts}) 9185f9996aaSopenharmony_ci parts_file = self.platforms_config_file.replace( 9195f9996aaSopenharmony_ci "platforms.build", "parts_config.json") 9205f9996aaSopenharmony_ci self._output_parts_config_json(all_parts, parts_file) 9215f9996aaSopenharmony_ci all_component_override_map.update(component_override_map) 9225f9996aaSopenharmony_ci write_json_file( 9235f9996aaSopenharmony_ci f"{self.config_output_dir}/component_override_map.json", all_component_override_map) 9245f9996aaSopenharmony_ci return overrided_components 9255f9996aaSopenharmony_ci 9265f9996aaSopenharmony_ci def _override_one_component(self, subsystem_info: dict, component: dict, build_file: str, all_parts: dict, overrided_components: dict, component_override_map: dict): 9275f9996aaSopenharmony_ci '''Description: Perform a replacement of a single component and return the component list update result. 9285f9996aaSopenharmony_ci @parameter:subsystem_info, component, build_file, all_parts, overrided_components 9295f9996aaSopenharmony_ci @return :True or False(Whether replacement has been performed) 9305f9996aaSopenharmony_ci ''' 9315f9996aaSopenharmony_ci splits = component["override"].split(":") 9325f9996aaSopenharmony_ci if len(splits) != 2: 9335f9996aaSopenharmony_ci LogUtil.hb_warning( 9345f9996aaSopenharmony_ci "{} override value is invalid format. Skip override process".format(build_file)) 9355f9996aaSopenharmony_ci return False 9365f9996aaSopenharmony_ci overrided_subsystem = splits[0] 9375f9996aaSopenharmony_ci overrided_component = splits[1] 9385f9996aaSopenharmony_ci if overrided_subsystem not in subsystem_info: 9395f9996aaSopenharmony_ci LogUtil.hb_warning( 9405f9996aaSopenharmony_ci "{} override invalid subsystem. Skip override process".format(build_file)) 9415f9996aaSopenharmony_ci return False 9425f9996aaSopenharmony_ci 9435f9996aaSopenharmony_ci founded_bundle = "" 9445f9996aaSopenharmony_ci 9455f9996aaSopenharmony_ci for bundle in subsystem_info[overrided_subsystem]["build_files"]: 9465f9996aaSopenharmony_ci if not bundle.endswith('bundle.json'): 9475f9996aaSopenharmony_ci continue 9485f9996aaSopenharmony_ci 9495f9996aaSopenharmony_ci bundle_obj = read_json_file(bundle) 9505f9996aaSopenharmony_ci 9515f9996aaSopenharmony_ci if bundle_obj.get("component", {}).get("name") == overrided_component: 9525f9996aaSopenharmony_ci founded_bundle = bundle 9535f9996aaSopenharmony_ci break 9545f9996aaSopenharmony_ci 9555f9996aaSopenharmony_ci if founded_bundle: 9565f9996aaSopenharmony_ci origin_component = read_json_file(build_file).get('component') 9575f9996aaSopenharmony_ci LogUtil.hb_warning( 9585f9996aaSopenharmony_ci f"You are trying to override \"{component['override']}\" with \"{origin_component.get('subsystem')}:{origin_component.get('name')}\". \nPlease ensure that the modules in \"{component['override']}\" only rely on the interfaces of other components through \"external_deps\"") 9595f9996aaSopenharmony_ci 9605f9996aaSopenharmony_ci # replace bundle.json in subsystem_info's build_files 9615f9996aaSopenharmony_ci subsystem_info[overrided_subsystem]["build_files"].remove( 9625f9996aaSopenharmony_ci founded_bundle) 9635f9996aaSopenharmony_ci 9645f9996aaSopenharmony_ci # Update parts.json generated by preloader, which means that new added components will not be installed 9655f9996aaSopenharmony_ci # Ensure that the overrided components will be installed 9665f9996aaSopenharmony_ci full_partname = f"{overrided_subsystem}:{overrided_component}" 9675f9996aaSopenharmony_ci if full_partname in all_parts: 9685f9996aaSopenharmony_ci all_parts.remove(full_partname) 9695f9996aaSopenharmony_ci 9705f9996aaSopenharmony_ci overrided_components[f"{component['subsystem']}:{component['name']}"] = { 9715f9996aaSopenharmony_ci 'subsystem': overrided_subsystem, 9725f9996aaSopenharmony_ci 'partName': overrided_component 9735f9996aaSopenharmony_ci } 9745f9996aaSopenharmony_ci component_override_map[overrided_component] = component["name"] 9755f9996aaSopenharmony_ci return True 9765f9996aaSopenharmony_ci LogUtil.hb_warning( 9775f9996aaSopenharmony_ci "{}:{} is not configured in product, \new add component will be installed!".format( 9785f9996aaSopenharmony_ci overrided_subsystem, overrided_component)) 9795f9996aaSopenharmony_ci return False 9805f9996aaSopenharmony_ci 9815f9996aaSopenharmony_ci def _output_parts_config_json(self, all_parts: dict, output_file: dict): 9825f9996aaSopenharmony_ci '''Description: Update the parts list file generated by preloader 9835f9996aaSopenharmony_ci @parameter: all_parts, output_file 9845f9996aaSopenharmony_ci @return :none 9855f9996aaSopenharmony_ci ''' 9865f9996aaSopenharmony_ci parts_config = {} 9875f9996aaSopenharmony_ci for part in all_parts: 9885f9996aaSopenharmony_ci part = part.replace(":", "_") 9895f9996aaSopenharmony_ci part = part.replace("-", "_") 9905f9996aaSopenharmony_ci part = part.replace(".", "_") 9915f9996aaSopenharmony_ci part = part.replace("/", "_") 9925f9996aaSopenharmony_ci parts_config[part] = True 9935f9996aaSopenharmony_ci write_json_file(output_file, parts_config) 994