xref: /build/hb/services/loader.py (revision 5f9996aa)
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