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, current_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 # not ohos platform toolchain, use current_toolchain 36 toolchain = current_toolchain 37 required_include_dir = True 38 return toolchain, required_include_dir 39 40 41def _get_components_info(components_info_dict, external_module_name): 42 external_module_result = {} 43 external_module_array = components_info_dict.get("innerapis") 44 for external_module in external_module_array: 45 if external_module.get("name") == external_module_name: 46 external_module_result = external_module 47 break 48 return external_module_result 49 50 51def _get_external_module_info(parts_inner_kits_info, components_info, external_part_name, 52 external_module_name, adapted_part_name): 53 _inner_kits_info_dict = parts_inner_kits_info.get(external_part_name) 54 if _inner_kits_info_dict is None: 55 raise Exception( 56 "external dep part '{}' doesn't exist.".format(external_part_name)) 57 if external_module_name in _inner_kits_info_dict: 58 external_module_desc_info = _inner_kits_info_dict.get( 59 external_module_name) 60 elif adapted_part_name: 61 _new_kits_info_dict = parts_inner_kits_info.get(adapted_part_name) 62 if _new_kits_info_dict is None: 63 raise Exception( 64 "part '{}' doesn't exist.".format(adapted_part_name)) 65 external_module_desc_info = _new_kits_info_dict.get( 66 external_module_name) 67 if external_module_desc_info is None: 68 raise Exception( 69 "external dep module '{}' doesn't exist in part '{}'.".format( 70 external_module_name, adapted_part_name)) 71 else: 72 _components_info_dict = components_info.get(external_part_name) 73 external_module_desc_info = _get_components_info(_components_info_dict, external_module_name) 74 if not external_module_desc_info: 75 raise Exception( 76 "external dep module '{}' doesn't exist in part '{}'.".format( 77 external_module_name, external_part_name)) 78 external_module_desc_info['prebuilt_enable'] = False 79 return external_module_desc_info 80 81 82def _get_external_module_from_sdk(sdk_base_dir, external_part_name, 83 external_module_name, adapted_part_name): 84 _sdk_info_file = os.path.join(sdk_base_dir, external_part_name, 85 "sdk_info.json") 86 subsystem_sdk_info = read_json_file(_sdk_info_file) 87 if subsystem_sdk_info is None: 88 raise Exception("part '{}' doesn't exist in sdk modules.".format( 89 external_part_name)) 90 91 _adapted = False 92 if external_module_name in subsystem_sdk_info: 93 sdk_module_info = subsystem_sdk_info.get(external_module_name) 94 elif adapted_part_name: 95 _new_sdk_info_file = os.path.join(sdk_base_dir, adapted_part_name, 96 "sdk_info.json") 97 _new_subsystem_sdk_info = read_json_file(_new_sdk_info_file) 98 if _new_subsystem_sdk_info is None: 99 raise Exception("part '{}' doesn't exist sdk modules.".format( 100 adapted_part_name)) 101 sdk_module_info = _new_subsystem_sdk_info.get(external_module_name) 102 if sdk_module_info is None: 103 raise Exception( 104 "external dep module '{}' doesn't exist in part '{}'.".format( 105 external_module_name, adapted_part_name)) 106 _adapted = True 107 else: 108 raise Exception( 109 "external dep module '{}' doesn't exist in part '{}'.".format( 110 external_module_name, external_part_name)) 111 return sdk_module_info, _adapted 112 113 114def _get_inner_kits_adapter_info(innerkits_adapter_info_file): 115 _parts_compatibility = {} 116 if os.path.exists(innerkits_adapter_info_file): 117 inner_kits_adapter_info = read_json_file(innerkits_adapter_info_file) 118 if inner_kits_adapter_info is None: 119 raise Exception("read inner_kits_adapter info failed.") 120 _parts_compatibility.update(inner_kits_adapter_info) 121 return _parts_compatibility 122 123 124def _parse_inner_kits_file(): 125 inner_kits_info_file = 'build_configs/parts_info/inner_kits_info.json' 126 all_kits_info_dict = read_json_file(inner_kits_info_file) 127 components_info_file = 'build_configs/parts_info/components.json' 128 components_info_dict = read_json_file(components_info_file) 129 return all_kits_info_dict, components_info_dict 130 131 132def main(): 133 parser = argparse.ArgumentParser() 134 parser.add_argument('--external-deps', nargs='*', required=True) 135 parser.add_argument('--parts-src-flag-file', required=True) 136 parser.add_argument('--sdk-base-dir', required=True) 137 parser.add_argument('--sdk-dir-name', required=True) 138 parser.add_argument('--external-deps-temp-file', required=True) 139 parser.add_argument('--use-sdk', dest='use_sdk', action='store_true') 140 parser.set_defaults(use_sdk=False) 141 parser.add_argument('--is-arkui-x', dest='is_arkui_x', action='store_true') 142 parser.add_argument('--current-toolchain', required=False, default='') 143 parser.add_argument('--component-override-map', default='', required=False) 144 parser.add_argument( 145 '--innerkits-adapter-info-file', 146 default='../../build/ohos/inner_kits_adapter.json') 147 args = parser.parse_args() 148 149 if len(args.external_deps) == 0: 150 result = {} 151 write_json_file(args.external_deps_temp_file, result) 152 return 0 153 154 # parts info 155 parts_src_flag = read_json_file(args.parts_src_flag_file) 156 # external deps list 157 external_deps = args.external_deps 158 # sdk base dir 159 sdk_base_dir = args.sdk_base_dir 160 sdk_dir_name = args.sdk_dir_name 161 use_sdk = args.use_sdk 162 163 deps = [] 164 libs = [] 165 include_dirs = [] 166 167 # load inner kits info file 168 all_kits_info_dict, components_info_dict = _parse_inner_kits_file() 169 if all_kits_info_dict is None: 170 raise Exception("read pre_build inner_kits_info failed.") 171 172 # load parts variants 173 parts_variants_info_file = 'build_configs/parts_info/parts_variants.json' 174 all_parts_variants_info = read_json_file(parts_variants_info_file) 175 if all_parts_variants_info is None: 176 raise Exception("read pre_build parts_variants failed.") 177 178 # load toolchains info 179 toolchain_variant_info_file = os.path.join('build_configs', 180 'platforms_info', 181 'toolchain_to_variant.json') 182 toolchain_variant_info = read_json_file(toolchain_variant_info_file) 183 184 # load auto install info 185 auto_install_part_file = "build_configs/auto_install_parts.json" 186 auto_install_parts = read_json_file(auto_install_part_file) 187 188 if toolchain_variant_info is None: 189 raise Exception("read pre_build parts_variants failed.") 190 toolchain_platform = toolchain_variant_info.get('toolchain_platform') 191 current_variant = toolchain_platform.get(args.current_toolchain) 192 platform_toolchain = toolchain_variant_info.get('platform_toolchain') 193 194 # compatibility interim 195 _parts_compatibility = _get_inner_kits_adapter_info( 196 args.innerkits_adapter_info_file) 197 198 for external_lib in external_deps: 199 deps_desc = external_lib.split(':') 200 external_part_name = deps_desc[0] 201 202 # If a part was assigned to override, replace the part 203 # Component_override_map is a map for origin part and new part. 204 if args.component_override_map: 205 component_override_map = read_json_file( 206 args.component_override_map) 207 for key, value in component_override_map.items(): 208 if external_part_name == key: 209 external_part_name = value 210 211 external_module_name = deps_desc[1] 212 213 # Usually the value is None 214 _adapted_part_name = _parts_compatibility.get(external_part_name) 215 216 # Check if the subsystem has source code 217 # hdf and third_party's external deps always valid because they need auto install 218 is_external_part_valid = external_part_name in parts_src_flag \ 219 or external_part_name in auto_install_parts 220 221 if not is_external_part_valid and args.is_arkui_x: 222 continue 223 224 if not use_sdk and is_external_part_valid: 225 external_module_desc_info = _get_external_module_info( 226 all_kits_info_dict, components_info_dict, external_part_name, external_module_name, 227 _adapted_part_name) 228 dep_label = external_module_desc_info.get('label') 229 230 part_variants_info = all_parts_variants_info.get(external_part_name) 231 if part_variants_info is None: 232 raise Exception( 233 "external deps part '{}' variants info is None.".format( 234 external_part_name)) 235 toolchain, required_include_dir = get_toolchain( 236 current_variant, part_variants_info.keys(), platform_toolchain, args.current_toolchain) 237 dep_label_with_tc = "{}({})".format(dep_label, toolchain) 238 deps += [dep_label_with_tc] 239 240 if required_include_dir is True and external_module_desc_info.get( 241 'type') == 'so': 242 include_dir = external_module_desc_info.get('header_base') 243 if include_dir: 244 include_dirs.append(include_dir) 245 246 # sdk prebuilt 247 if external_module_desc_info.get('prebuilt_enable'): 248 libs += [external_module_desc_info.get('prebuilt_source')] 249 else: 250 sdk_module_info, adapted_ok = _get_external_module_from_sdk( 251 sdk_base_dir, external_part_name, external_module_name, 252 _adapted_part_name) 253 254 if adapted_ok is True: 255 _external_part_name = _adapted_part_name 256 else: 257 _external_part_name = external_part_name 258 deps += [ 259 "//{}/{}:{}".format(sdk_dir_name, _external_part_name, 260 external_module_name) 261 ] 262 # java sdk module does not need to add libs 263 if not (sdk_module_info.get('type') 264 and sdk_module_info.get('type') == 'jar'): 265 external_lib_source = sdk_module_info.get('source') 266 libs += [ 267 "//{}/{}/{}".format(sdk_dir_name, _external_part_name, 268 external_lib_source) 269 ] 270 271 result = {} 272 result['deps'] = deps 273 if libs: 274 result['libs'] = libs 275 if include_dirs: 276 result['include_dirs'] = include_dirs 277 278 write_json_file(args.external_deps_temp_file, result) 279 return 0 280 281 282if __name__ == '__main__': 283 sys.exit(main()) 284