15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ciimport argparse
175f9996aaSopenharmony_ciimport os
185f9996aaSopenharmony_ciimport sys
195f9996aaSopenharmony_ci
205f9996aaSopenharmony_cisys.path.append(
215f9996aaSopenharmony_ci    os.path.dirname(os.path.dirname(os.path.dirname(
225f9996aaSopenharmony_ci        os.path.abspath(__file__)))))
235f9996aaSopenharmony_cifrom scripts.util.file_utils import read_json_file, write_json_file  # noqa: E402
245f9996aaSopenharmony_ci
255f9996aaSopenharmony_ci
265f9996aaSopenharmony_cidef get_toolchain(current_variant, external_part_variants, platform_toolchain, current_toolchain):
275f9996aaSopenharmony_ci    if current_variant == 'phone':
285f9996aaSopenharmony_ci        toolchain = platform_toolchain.get(current_variant)
295f9996aaSopenharmony_ci        required_include_dir = False
305f9996aaSopenharmony_ci    else:
315f9996aaSopenharmony_ci        if current_variant in external_part_variants:
325f9996aaSopenharmony_ci            toolchain = platform_toolchain.get(current_variant)
335f9996aaSopenharmony_ci            required_include_dir = False
345f9996aaSopenharmony_ci        else:
355f9996aaSopenharmony_ci            # not ohos platform toolchain, use current_toolchain
365f9996aaSopenharmony_ci            toolchain = current_toolchain
375f9996aaSopenharmony_ci            required_include_dir = True
385f9996aaSopenharmony_ci    return toolchain, required_include_dir
395f9996aaSopenharmony_ci
405f9996aaSopenharmony_ci
415f9996aaSopenharmony_cidef _get_components_info(components_info_dict, external_module_name):
425f9996aaSopenharmony_ci    external_module_result = {}
435f9996aaSopenharmony_ci    external_module_array = components_info_dict.get("innerapis")
445f9996aaSopenharmony_ci    for external_module in external_module_array:
455f9996aaSopenharmony_ci        if external_module.get("name") == external_module_name:
465f9996aaSopenharmony_ci            external_module_result = external_module
475f9996aaSopenharmony_ci            break
485f9996aaSopenharmony_ci    return external_module_result
495f9996aaSopenharmony_ci
505f9996aaSopenharmony_ci
515f9996aaSopenharmony_cidef _get_external_module_info(parts_inner_kits_info, components_info, external_part_name,
525f9996aaSopenharmony_ci                              external_module_name, adapted_part_name):
535f9996aaSopenharmony_ci    _inner_kits_info_dict = parts_inner_kits_info.get(external_part_name)
545f9996aaSopenharmony_ci    if _inner_kits_info_dict is None:
555f9996aaSopenharmony_ci        raise Exception(
565f9996aaSopenharmony_ci            "external dep part '{}' doesn't exist.".format(external_part_name))
575f9996aaSopenharmony_ci    if external_module_name in _inner_kits_info_dict:
585f9996aaSopenharmony_ci        external_module_desc_info = _inner_kits_info_dict.get(
595f9996aaSopenharmony_ci            external_module_name)
605f9996aaSopenharmony_ci    elif adapted_part_name:
615f9996aaSopenharmony_ci        _new_kits_info_dict = parts_inner_kits_info.get(adapted_part_name)
625f9996aaSopenharmony_ci        if _new_kits_info_dict is None:
635f9996aaSopenharmony_ci            raise Exception(
645f9996aaSopenharmony_ci                "part '{}' doesn't exist.".format(adapted_part_name))
655f9996aaSopenharmony_ci        external_module_desc_info = _new_kits_info_dict.get(
665f9996aaSopenharmony_ci            external_module_name)
675f9996aaSopenharmony_ci        if external_module_desc_info is None:
685f9996aaSopenharmony_ci            raise Exception(
695f9996aaSopenharmony_ci                "external dep module '{}' doesn't exist in part '{}'.".format(
705f9996aaSopenharmony_ci                    external_module_name, adapted_part_name))
715f9996aaSopenharmony_ci    else:
725f9996aaSopenharmony_ci        _components_info_dict = components_info.get(external_part_name)
735f9996aaSopenharmony_ci        external_module_desc_info = _get_components_info(_components_info_dict, external_module_name)
745f9996aaSopenharmony_ci        if not external_module_desc_info:
755f9996aaSopenharmony_ci            raise Exception(
765f9996aaSopenharmony_ci                "external dep module '{}' doesn't exist in part '{}'.".format(
775f9996aaSopenharmony_ci                    external_module_name, external_part_name))
785f9996aaSopenharmony_ci        external_module_desc_info['prebuilt_enable'] = False
795f9996aaSopenharmony_ci    return external_module_desc_info
805f9996aaSopenharmony_ci
815f9996aaSopenharmony_ci
825f9996aaSopenharmony_cidef _get_external_module_from_sdk(sdk_base_dir, external_part_name,
835f9996aaSopenharmony_ci                                  external_module_name, adapted_part_name):
845f9996aaSopenharmony_ci    _sdk_info_file = os.path.join(sdk_base_dir, external_part_name,
855f9996aaSopenharmony_ci                                  "sdk_info.json")
865f9996aaSopenharmony_ci    subsystem_sdk_info = read_json_file(_sdk_info_file)
875f9996aaSopenharmony_ci    if subsystem_sdk_info is None:
885f9996aaSopenharmony_ci        raise Exception("part '{}' doesn't exist in sdk modules.".format(
895f9996aaSopenharmony_ci            external_part_name))
905f9996aaSopenharmony_ci
915f9996aaSopenharmony_ci    _adapted = False
925f9996aaSopenharmony_ci    if external_module_name in subsystem_sdk_info:
935f9996aaSopenharmony_ci        sdk_module_info = subsystem_sdk_info.get(external_module_name)
945f9996aaSopenharmony_ci    elif adapted_part_name:
955f9996aaSopenharmony_ci        _new_sdk_info_file = os.path.join(sdk_base_dir, adapted_part_name,
965f9996aaSopenharmony_ci                                          "sdk_info.json")
975f9996aaSopenharmony_ci        _new_subsystem_sdk_info = read_json_file(_new_sdk_info_file)
985f9996aaSopenharmony_ci        if _new_subsystem_sdk_info is None:
995f9996aaSopenharmony_ci            raise Exception("part '{}' doesn't exist sdk modules.".format(
1005f9996aaSopenharmony_ci                adapted_part_name))
1015f9996aaSopenharmony_ci        sdk_module_info = _new_subsystem_sdk_info.get(external_module_name)
1025f9996aaSopenharmony_ci        if sdk_module_info is None:
1035f9996aaSopenharmony_ci            raise Exception(
1045f9996aaSopenharmony_ci                "external dep module '{}' doesn't exist in part '{}'.".format(
1055f9996aaSopenharmony_ci                    external_module_name, adapted_part_name))
1065f9996aaSopenharmony_ci        _adapted = True
1075f9996aaSopenharmony_ci    else:
1085f9996aaSopenharmony_ci        raise Exception(
1095f9996aaSopenharmony_ci            "external dep module '{}' doesn't exist in part '{}'.".format(
1105f9996aaSopenharmony_ci                external_module_name, external_part_name))
1115f9996aaSopenharmony_ci    return sdk_module_info, _adapted
1125f9996aaSopenharmony_ci
1135f9996aaSopenharmony_ci
1145f9996aaSopenharmony_cidef _get_inner_kits_adapter_info(innerkits_adapter_info_file):
1155f9996aaSopenharmony_ci    _parts_compatibility = {}
1165f9996aaSopenharmony_ci    if os.path.exists(innerkits_adapter_info_file):
1175f9996aaSopenharmony_ci        inner_kits_adapter_info = read_json_file(innerkits_adapter_info_file)
1185f9996aaSopenharmony_ci        if inner_kits_adapter_info is None:
1195f9996aaSopenharmony_ci            raise Exception("read inner_kits_adapter info failed.")
1205f9996aaSopenharmony_ci        _parts_compatibility.update(inner_kits_adapter_info)
1215f9996aaSopenharmony_ci    return _parts_compatibility
1225f9996aaSopenharmony_ci
1235f9996aaSopenharmony_ci
1245f9996aaSopenharmony_cidef _parse_inner_kits_file():
1255f9996aaSopenharmony_ci    inner_kits_info_file = 'build_configs/parts_info/inner_kits_info.json'
1265f9996aaSopenharmony_ci    all_kits_info_dict = read_json_file(inner_kits_info_file)
1275f9996aaSopenharmony_ci    components_info_file = 'build_configs/parts_info/components.json'
1285f9996aaSopenharmony_ci    components_info_dict = read_json_file(components_info_file)
1295f9996aaSopenharmony_ci    return all_kits_info_dict, components_info_dict
1305f9996aaSopenharmony_ci
1315f9996aaSopenharmony_ci
1325f9996aaSopenharmony_cidef main():
1335f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
1345f9996aaSopenharmony_ci    parser.add_argument('--external-deps', nargs='*', required=True)
1355f9996aaSopenharmony_ci    parser.add_argument('--parts-src-flag-file', required=True)
1365f9996aaSopenharmony_ci    parser.add_argument('--sdk-base-dir', required=True)
1375f9996aaSopenharmony_ci    parser.add_argument('--sdk-dir-name', required=True)
1385f9996aaSopenharmony_ci    parser.add_argument('--external-deps-temp-file', required=True)
1395f9996aaSopenharmony_ci    parser.add_argument('--use-sdk', dest='use_sdk', action='store_true')
1405f9996aaSopenharmony_ci    parser.set_defaults(use_sdk=False)
1415f9996aaSopenharmony_ci    parser.add_argument('--is-arkui-x', dest='is_arkui_x', action='store_true')
1425f9996aaSopenharmony_ci    parser.add_argument('--current-toolchain', required=False, default='')
1435f9996aaSopenharmony_ci    parser.add_argument('--component-override-map', default='', required=False)
1445f9996aaSopenharmony_ci    parser.add_argument(
1455f9996aaSopenharmony_ci        '--innerkits-adapter-info-file',
1465f9996aaSopenharmony_ci        default='../../build/ohos/inner_kits_adapter.json')
1475f9996aaSopenharmony_ci    args = parser.parse_args()
1485f9996aaSopenharmony_ci
1495f9996aaSopenharmony_ci    if len(args.external_deps) == 0:
1505f9996aaSopenharmony_ci        result = {}
1515f9996aaSopenharmony_ci        write_json_file(args.external_deps_temp_file, result)
1525f9996aaSopenharmony_ci        return 0
1535f9996aaSopenharmony_ci
1545f9996aaSopenharmony_ci    # parts info
1555f9996aaSopenharmony_ci    parts_src_flag = read_json_file(args.parts_src_flag_file)
1565f9996aaSopenharmony_ci    # external deps list
1575f9996aaSopenharmony_ci    external_deps = args.external_deps
1585f9996aaSopenharmony_ci    # sdk base dir
1595f9996aaSopenharmony_ci    sdk_base_dir = args.sdk_base_dir
1605f9996aaSopenharmony_ci    sdk_dir_name = args.sdk_dir_name
1615f9996aaSopenharmony_ci    use_sdk = args.use_sdk
1625f9996aaSopenharmony_ci
1635f9996aaSopenharmony_ci    deps = []
1645f9996aaSopenharmony_ci    libs = []
1655f9996aaSopenharmony_ci    include_dirs = []
1665f9996aaSopenharmony_ci
1675f9996aaSopenharmony_ci    # load inner kits info file
1685f9996aaSopenharmony_ci    all_kits_info_dict, components_info_dict = _parse_inner_kits_file()
1695f9996aaSopenharmony_ci    if all_kits_info_dict is None:
1705f9996aaSopenharmony_ci        raise Exception("read pre_build inner_kits_info failed.")
1715f9996aaSopenharmony_ci
1725f9996aaSopenharmony_ci    # load parts variants
1735f9996aaSopenharmony_ci    parts_variants_info_file = 'build_configs/parts_info/parts_variants.json'
1745f9996aaSopenharmony_ci    all_parts_variants_info = read_json_file(parts_variants_info_file)
1755f9996aaSopenharmony_ci    if all_parts_variants_info is None:
1765f9996aaSopenharmony_ci        raise Exception("read pre_build parts_variants failed.")
1775f9996aaSopenharmony_ci
1785f9996aaSopenharmony_ci    # load toolchains info
1795f9996aaSopenharmony_ci    toolchain_variant_info_file = os.path.join('build_configs',
1805f9996aaSopenharmony_ci                                               'platforms_info',
1815f9996aaSopenharmony_ci                                               'toolchain_to_variant.json')
1825f9996aaSopenharmony_ci    toolchain_variant_info = read_json_file(toolchain_variant_info_file)
1835f9996aaSopenharmony_ci
1845f9996aaSopenharmony_ci    # load auto install info
1855f9996aaSopenharmony_ci    auto_install_part_file = "build_configs/auto_install_parts.json"
1865f9996aaSopenharmony_ci    auto_install_parts = read_json_file(auto_install_part_file)
1875f9996aaSopenharmony_ci
1885f9996aaSopenharmony_ci    if toolchain_variant_info is None:
1895f9996aaSopenharmony_ci        raise Exception("read pre_build parts_variants failed.")
1905f9996aaSopenharmony_ci    toolchain_platform = toolchain_variant_info.get('toolchain_platform')
1915f9996aaSopenharmony_ci    current_variant = toolchain_platform.get(args.current_toolchain)
1925f9996aaSopenharmony_ci    platform_toolchain = toolchain_variant_info.get('platform_toolchain')
1935f9996aaSopenharmony_ci
1945f9996aaSopenharmony_ci    # compatibility interim
1955f9996aaSopenharmony_ci    _parts_compatibility = _get_inner_kits_adapter_info(
1965f9996aaSopenharmony_ci        args.innerkits_adapter_info_file)
1975f9996aaSopenharmony_ci
1985f9996aaSopenharmony_ci    for external_lib in external_deps:
1995f9996aaSopenharmony_ci        deps_desc = external_lib.split(':')
2005f9996aaSopenharmony_ci        external_part_name = deps_desc[0]
2015f9996aaSopenharmony_ci
2025f9996aaSopenharmony_ci        # If a part was assigned to override, replace the part
2035f9996aaSopenharmony_ci        # Component_override_map is a map for origin part and new part.
2045f9996aaSopenharmony_ci        if args.component_override_map:
2055f9996aaSopenharmony_ci            component_override_map = read_json_file(
2065f9996aaSopenharmony_ci                args.component_override_map)
2075f9996aaSopenharmony_ci            for key, value in component_override_map.items():
2085f9996aaSopenharmony_ci                if external_part_name == key:
2095f9996aaSopenharmony_ci                    external_part_name = value
2105f9996aaSopenharmony_ci
2115f9996aaSopenharmony_ci        external_module_name = deps_desc[1]
2125f9996aaSopenharmony_ci
2135f9996aaSopenharmony_ci        # Usually the value is None
2145f9996aaSopenharmony_ci        _adapted_part_name = _parts_compatibility.get(external_part_name)
2155f9996aaSopenharmony_ci
2165f9996aaSopenharmony_ci        # Check if the subsystem has source code
2175f9996aaSopenharmony_ci        # hdf and third_party's external deps always valid because they need auto install
2185f9996aaSopenharmony_ci        is_external_part_valid = external_part_name in parts_src_flag \
2195f9996aaSopenharmony_ci            or external_part_name in auto_install_parts
2205f9996aaSopenharmony_ci
2215f9996aaSopenharmony_ci        if not is_external_part_valid and args.is_arkui_x:
2225f9996aaSopenharmony_ci            continue
2235f9996aaSopenharmony_ci
2245f9996aaSopenharmony_ci        if not use_sdk and is_external_part_valid:
2255f9996aaSopenharmony_ci            external_module_desc_info = _get_external_module_info(
2265f9996aaSopenharmony_ci                all_kits_info_dict, components_info_dict, external_part_name, external_module_name,
2275f9996aaSopenharmony_ci                _adapted_part_name)
2285f9996aaSopenharmony_ci            dep_label = external_module_desc_info.get('label')
2295f9996aaSopenharmony_ci
2305f9996aaSopenharmony_ci            part_variants_info = all_parts_variants_info.get(external_part_name)
2315f9996aaSopenharmony_ci            if part_variants_info is None:
2325f9996aaSopenharmony_ci                raise Exception(
2335f9996aaSopenharmony_ci                    "external deps part '{}' variants info is None.".format(
2345f9996aaSopenharmony_ci                        external_part_name))
2355f9996aaSopenharmony_ci            toolchain, required_include_dir = get_toolchain(
2365f9996aaSopenharmony_ci                current_variant, part_variants_info.keys(), platform_toolchain, args.current_toolchain)
2375f9996aaSopenharmony_ci            dep_label_with_tc = "{}({})".format(dep_label, toolchain)
2385f9996aaSopenharmony_ci            deps += [dep_label_with_tc]
2395f9996aaSopenharmony_ci
2405f9996aaSopenharmony_ci            if required_include_dir is True and external_module_desc_info.get(
2415f9996aaSopenharmony_ci                    'type') == 'so':
2425f9996aaSopenharmony_ci                include_dir = external_module_desc_info.get('header_base')
2435f9996aaSopenharmony_ci                if include_dir:
2445f9996aaSopenharmony_ci                    include_dirs.append(include_dir)
2455f9996aaSopenharmony_ci
2465f9996aaSopenharmony_ci            # sdk prebuilt
2475f9996aaSopenharmony_ci            if external_module_desc_info.get('prebuilt_enable'):
2485f9996aaSopenharmony_ci                libs += [external_module_desc_info.get('prebuilt_source')]
2495f9996aaSopenharmony_ci        else:
2505f9996aaSopenharmony_ci            sdk_module_info, adapted_ok = _get_external_module_from_sdk(
2515f9996aaSopenharmony_ci                sdk_base_dir, external_part_name, external_module_name,
2525f9996aaSopenharmony_ci                _adapted_part_name)
2535f9996aaSopenharmony_ci
2545f9996aaSopenharmony_ci            if adapted_ok is True:
2555f9996aaSopenharmony_ci                _external_part_name = _adapted_part_name
2565f9996aaSopenharmony_ci            else:
2575f9996aaSopenharmony_ci                _external_part_name = external_part_name
2585f9996aaSopenharmony_ci            deps += [
2595f9996aaSopenharmony_ci                "//{}/{}:{}".format(sdk_dir_name, _external_part_name,
2605f9996aaSopenharmony_ci                                    external_module_name)
2615f9996aaSopenharmony_ci            ]
2625f9996aaSopenharmony_ci            # java sdk module does not need to add libs
2635f9996aaSopenharmony_ci            if not (sdk_module_info.get('type')
2645f9996aaSopenharmony_ci                    and sdk_module_info.get('type') == 'jar'):
2655f9996aaSopenharmony_ci                external_lib_source = sdk_module_info.get('source')
2665f9996aaSopenharmony_ci                libs += [
2675f9996aaSopenharmony_ci                    "//{}/{}/{}".format(sdk_dir_name, _external_part_name,
2685f9996aaSopenharmony_ci                                        external_lib_source)
2695f9996aaSopenharmony_ci                ]
2705f9996aaSopenharmony_ci
2715f9996aaSopenharmony_ci    result = {}
2725f9996aaSopenharmony_ci    result['deps'] = deps
2735f9996aaSopenharmony_ci    if libs:
2745f9996aaSopenharmony_ci        result['libs'] = libs
2755f9996aaSopenharmony_ci    if include_dirs:
2765f9996aaSopenharmony_ci        result['include_dirs'] = include_dirs
2775f9996aaSopenharmony_ci
2785f9996aaSopenharmony_ci    write_json_file(args.external_deps_temp_file, result)
2795f9996aaSopenharmony_ci    return 0
2805f9996aaSopenharmony_ci
2815f9996aaSopenharmony_ci
2825f9996aaSopenharmony_ciif __name__ == '__main__':
2835f9996aaSopenharmony_ci    sys.exit(main())
284