1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import argparse 17import os 18import sys 19 20sys.path.append( 21 os.path.dirname(os.path.dirname(os.path.dirname( 22 os.path.abspath(__file__))))) 23from scripts.util.file_utils import read_json_file, write_json_file # noqa: E402 24 25 26def get_toolchain(current_variant, external_part_variants, platform_toolchain): 27 if current_variant == 'phone': 28 toolchain = platform_toolchain.get(current_variant) 29 required_include_dir = False 30 else: 31 if current_variant in external_part_variants: 32 toolchain = platform_toolchain.get(current_variant) 33 required_include_dir = False 34 else: 35 toolchain = platform_toolchain.get('phone') 36 required_include_dir = True 37 return toolchain, required_include_dir 38 39 40def _get_external_module_info(parts_inner_kits_info, external_part_name, 41 external_module_name, adapted_part_name): 42 _inner_kits_info_dict = parts_inner_kits_info.get(external_part_name) 43 if _inner_kits_info_dict is None: 44 raise Exception( 45 "external dep part '{}' doesn't exist.".format(external_part_name)) 46 if external_module_name in _inner_kits_info_dict: 47 external_module_desc_info = _inner_kits_info_dict.get( 48 external_module_name) 49 elif adapted_part_name: 50 _new_kits_info_dict = parts_inner_kits_info.get(adapted_part_name) 51 if _new_kits_info_dict is None: 52 raise Exception( 53 "part '{}' doesn't exist.".format(adapted_part_name)) 54 external_module_desc_info = _new_kits_info_dict.get( 55 external_module_name) 56 if external_module_desc_info is None: 57 raise Exception( 58 "external dep module '{}' doesn't exist in part '{}'.".format( 59 external_module_name, adapted_part_name)) 60 else: 61 raise Exception( 62 "external dep module '{}' doesn't exist in part '{}'.".format( 63 external_module_name, external_part_name)) 64 return external_module_desc_info 65 66 67def _get_external_module_from_sdk(sdk_base_dir, external_part_name, 68 external_module_name, adapted_part_name): 69 _sdk_info_file = os.path.join(sdk_base_dir, external_part_name, 70 "sdk_info.json") 71 subsystem_sdk_info = read_json_file(_sdk_info_file) 72 if subsystem_sdk_info is None: 73 raise Exception("part '{}' doesn't exist in sdk modules.".format( 74 external_part_name)) 75 76 _adapted = False 77 if external_module_name in subsystem_sdk_info: 78 sdk_module_info = subsystem_sdk_info.get(external_module_name) 79 elif adapted_part_name: 80 _new_sdk_info_file = os.path.join(sdk_base_dir, adapted_part_name, 81 "sdk_info.json") 82 _new_subsystem_sdk_info = read_json_file(_new_sdk_info_file) 83 if _new_subsystem_sdk_info is None: 84 raise Exception("part '{}' doesn't exist sdk modules.".format( 85 adapted_part_name)) 86 sdk_module_info = _new_subsystem_sdk_info.get(external_module_name) 87 if sdk_module_info is None: 88 raise Exception( 89 "external dep module '{}' doesn't exist in part '{}'.".format( 90 external_module_name, adapted_part_name)) 91 _adapted = True 92 else: 93 raise Exception( 94 "external dep module '{}' doesn't exist in part '{}'.".format( 95 external_module_name, external_part_name)) 96 return sdk_module_info, _adapted 97 98 99def _get_inner_kits_adapter_info(innerkits_adapter_info_file): 100 _parts_compatibility = {} 101 if os.path.exists(innerkits_adapter_info_file): 102 inner_kits_adapter_info = read_json_file(innerkits_adapter_info_file) 103 if inner_kits_adapter_info is None: 104 raise Exception("read inner_kits_adapter info failed.") 105 _parts_compatibility.update(inner_kits_adapter_info) 106 return _parts_compatibility 107 108 109def main(): 110 parser = argparse.ArgumentParser() 111 parser.add_argument('--external-deps', nargs='*', required=True) 112 parser.add_argument('--parts-src-flag-file', required=True) 113 parser.add_argument('--sdk-base-dir', required=True) 114 parser.add_argument('--sdk-dir-name', required=True) 115 parser.add_argument('--external-deps-temp-file', required=True) 116 parser.add_argument('--use-sdk', dest='use_sdk', action='store_true') 117 parser.set_defaults(use_sdk=False) 118 parser.add_argument('--current-toolchain', required=False, default='') 119 parser.add_argument( 120 '--innerkits-adapter-info-file', 121 default='../../build/ohos/inner_kits_adapter.json') 122 args = parser.parse_args() 123 124 if len(args.external_deps) == 0: 125 result = {} 126 write_json_file(args.external_deps_temp_file, result) 127 return 0 128 129 # parts info 130 parts_src_flag = read_json_file(args.parts_src_flag_file) 131 # external deps list 132 external_deps = args.external_deps 133 # sdk base dir 134 sdk_base_dir = args.sdk_base_dir 135 sdk_dir_name = args.sdk_dir_name 136 use_sdk = args.use_sdk 137 138 deps = [] 139 libs = [] 140 include_dirs = [] 141 142 # load inner kits info file 143 inner_kits_info_file = 'build_configs/parts_info/inner_kits_info.json' 144 all_kits_info_dict = read_json_file(inner_kits_info_file) 145 if all_kits_info_dict is None: 146 raise Exception("read pre_build inner_kits_info failed.") 147 148 # load parts variants 149 parts_variants_info_file = 'build_configs/parts_info/parts_variants.json' 150 all_parts_variants_info = read_json_file(parts_variants_info_file) 151 if all_parts_variants_info is None: 152 raise Exception("read pre_build parts_variants failed.") 153 154 # load toolchains info 155 toolchain_variant_info_file = os.path.join('build_configs', 156 'platforms_info', 157 'toolchain_to_variant.json') 158 toolchain_variant_info = read_json_file(toolchain_variant_info_file) 159 160 # load auto install info 161 auto_install_part_file = "build_configs/auto_install_parts.json" 162 auto_install_parts = read_json_file(auto_install_part_file) 163 164 if toolchain_variant_info is None: 165 raise Exception("read pre_build parts_variants failed.") 166 toolchain_platform = toolchain_variant_info.get('toolchain_platform') 167 current_variant = toolchain_platform.get(args.current_toolchain) 168 if not current_variant: 169 current_variant = 'phone' 170 platform_toolchain = toolchain_variant_info.get('platform_toolchain') 171 172 # compatibility interim 173 _parts_compatibility = _get_inner_kits_adapter_info( 174 args.innerkits_adapter_info_file) 175 176 for external_lib in external_deps: 177 deps_desc = external_lib.split(':') 178 external_part_name = deps_desc[0] 179 external_module_name = deps_desc[1] 180 181 # Usually the value is None 182 _adapted_part_name = _parts_compatibility.get(external_part_name) 183 184 # Check if the subsystem has source code 185 # hdf and third_party's external deps always valid because they need auto install 186 is_external_part_valid = external_part_name in parts_src_flag \ 187 or external_part_name in auto_install_parts 188 189 if not use_sdk and is_external_part_valid: 190 external_module_desc_info = _get_external_module_info( 191 all_kits_info_dict, external_part_name, external_module_name, 192 _adapted_part_name) 193 dep_label = external_module_desc_info['label'] 194 195 part_variants_info = all_parts_variants_info.get(external_part_name) 196 if part_variants_info is None: 197 raise Exception( 198 "external deps part '{}' variants info is None.".format( 199 external_part_name)) 200 toolchain, required_include_dir = get_toolchain( 201 current_variant, part_variants_info.keys(), platform_toolchain) 202 dep_label_with_tc = "{}({})".format(dep_label, toolchain) 203 deps += [dep_label_with_tc] 204 205 if required_include_dir is True and external_module_desc_info.get( 206 'type') == 'so': 207 include_dir = external_module_desc_info.get('header_base') 208 include_dirs.append(include_dir) 209 210 # sdk prebuilt 211 if external_module_desc_info['prebuilt_enable']: 212 libs += [external_module_desc_info['prebuilt_source']] 213 else: 214 sdk_module_info, adapted_ok = _get_external_module_from_sdk( 215 sdk_base_dir, external_part_name, external_module_name, 216 _adapted_part_name) 217 218 if adapted_ok is True: 219 _external_part_name = _adapted_part_name 220 else: 221 _external_part_name = external_part_name 222 deps += [ 223 "//{}/{}:{}".format(sdk_dir_name, _external_part_name, 224 external_module_name) 225 ] 226 # java sdk module does not need to add libs 227 if not (sdk_module_info.get('type') 228 and sdk_module_info.get('type') == 'jar'): 229 external_lib_source = sdk_module_info.get('source') 230 libs += [ 231 "//{}/{}/{}".format(sdk_dir_name, _external_part_name, 232 external_lib_source) 233 ] 234 235 result = {} 236 if deps: 237 result['deps'] = deps 238 if libs: 239 result['libs'] = libs 240 if include_dirs: 241 result['include_dirs'] = include_dirs 242 243 write_json_file(args.external_deps_temp_file, result) 244 return 0 245 246 247if __name__ == '__main__': 248 sys.exit(main()) 249