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 sys 17import os 18import merge_platform_build 19 20sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 21from scripts.util.file_utils import read_json_file, write_json_file # noqa: E402 22 23 24class PlatformsLoader: 25 def __init__(self, platforms_config_file, source_root_dir, root_build_dir, 26 target_arch, scalable_build): 27 self._platforms_config_file = platforms_config_file 28 self._source_root_dir = source_root_dir 29 self._root_build_dir = root_build_dir 30 self._platforms_info = {} 31 self._all_parts = {} 32 self._all_stubs = {} 33 self._is_load = False 34 self._target_arch = target_arch 35 self._scalable_build = scalable_build 36 37 def _read_platforms_config(self): 38 if not os.path.exists(self._platforms_config_file): 39 raise Exception("config file '{}' doesn't exist.".format( 40 self._platforms_config_file)) 41 config_info = read_json_file(self._platforms_config_file) 42 if config_info is None: 43 raise Exception("read file '{}' failed.".format( 44 self._platforms_config_file)) 45 config_version = config_info.get('version') 46 platforms_info = config_info.get('platforms') 47 48 platforms_config = {} 49 for _name, _platform_infos in platforms_info.items(): 50 if config_version >= 2: 51 _info = _platform_infos 52 target_os = _info.get('target_os') 53 target_cpu = _info.get('target_cpu') 54 if target_os is None or target_cpu is None: 55 error_info = "platform '{}' config incorrect,"\ 56 "target_os or target_cpu is None." 57 raise Exception(error_info.format(_name)) 58 arch = "{}_{}".format(target_os, target_cpu) 59 if arch in platforms_config: 60 _infos = platforms_config.get(arch) 61 else: 62 _infos = {} 63 _infos[_name] = _info 64 platforms_config[arch] = _infos 65 else: 66 for _info in _platform_infos: 67 target_os = _info.get('target_os') 68 target_cpu = _info.get('target_cpu') 69 if target_os is None or target_cpu is None: 70 error_info = "platform '{}' config incorrect,"\ 71 "target_os or target_cpu is None." 72 raise Exception(error_info.format(_name)) 73 arch = "{}_{}".format(target_os, target_cpu) 74 if arch in platforms_config: 75 _infos = platforms_config.get(arch) 76 else: 77 _infos = {} 78 _infos[_name] = _info 79 platforms_config[arch] = _infos 80 return platforms_config 81 82 @staticmethod 83 def _load_platform_config(platform_config_file): 84 if not os.path.exists(platform_config_file): 85 raise Exception( 86 "config file '{}' doesn't exist.".format(platform_config_file)) 87 _platform_config = read_json_file(platform_config_file) 88 if _platform_config is None: 89 raise Exception( 90 "read file '{}' failed.".format(platform_config_file)) 91 if 'parts' in _platform_config: 92 parts = _platform_config.get('parts') 93 else: 94 parts = [] 95 if 'stub_parts' in _platform_config: 96 stub_parts = _platform_config.get('stub_parts') 97 else: 98 stub_parts = [] 99 return parts, stub_parts 100 101 def _loading(self): 102 if self._is_load: 103 return 104 all_platforms_config = self._read_platforms_config() 105 _platforms_info = all_platforms_config.get(self._target_arch) 106 config_base_dir = os.path.dirname(self._platforms_config_file) 107 all_parts = {} 108 all_stubs = {} 109 for _platform_name, _info in _platforms_info.items(): 110 if self._scalable_build is False: 111 _file_name = _info.get('parts_config') 112 if _file_name is None: 113 _file_name = os.path.join( 114 'target_platforms', "{}.build".format(_platform_name)) 115 _platform_config_file = os.path.join(config_base_dir, 116 _file_name) 117 else: 118 required_build_file = os.path.join( 119 config_base_dir, _info.get('base_parts_config')) 120 optional_build_file = os.path.join( 121 config_base_dir, _info.get('optional_parts_config')) 122 stub_build_file = os.path.join(config_base_dir, 123 _info.get('stub_parts_config')) 124 _platform_config_file = '{}.build'.format(_platform_name) 125 126 merge_platform_build.do_merge(required_build_file, 127 optional_build_file, 128 stub_build_file, 129 _platform_config_file) 130 131 parts, stubs = self._load_platform_config(_platform_config_file) 132 all_parts[_platform_name] = parts 133 all_stubs[_platform_name] = stubs 134 135 self._platforms_info = _platforms_info 136 self._all_parts = all_parts 137 self._all_stubs = all_stubs 138 self._is_load = True 139 140 def get_all_parts(self): 141 self._loading() 142 all_parts = {} 143 for _platform, _parts in self._all_parts.items(): 144 part_list = [] 145 for part_def in _parts: 146 _part_name = part_def.split(':')[1] 147 part_list.append(_part_name) 148 all_parts[_platform] = part_list 149 return all_parts 150 151 def get_all_stubs(self): 152 self._loading() 153 all_parts = {} 154 for _platform, _parts in self._all_stubs.items(): 155 part_list = [] 156 for part_def in _parts: 157 _part_name = part_def.split(':')[1] 158 part_list.append(_part_name) 159 all_parts[_platform] = part_list 160 return all_parts 161 162 def platforms_toolchain(self): 163 self._loading() 164 platform_toolchain = {} 165 toolchain_platform = {} 166 for key, val in self._platforms_info.items(): 167 _toolchain = val.get('toolchain') 168 platform_toolchain[key] = _toolchain 169 toolchain_platform[_toolchain] = key 170 _result = { 171 "platform_toolchain": platform_toolchain, 172 "toolchain_platform": toolchain_platform 173 } 174 return _result 175 176 177def get_platforms_info(platforms_config_file, source_root_dir, root_build_dir, 178 target_arch, config_output_relpath, scalable_build): 179 platform_loader = PlatformsLoader(platforms_config_file, source_root_dir, 180 root_build_dir, target_arch, 181 scalable_build) 182 183 platforms_info_output_dir = 'platforms_info' 184 all_parts = platform_loader.get_all_parts() 185 all_parts_file = os.path.join(source_root_dir, config_output_relpath, 186 platforms_info_output_dir, "all_parts.json") 187 write_json_file(all_parts_file, all_parts) 188 189 # variant to toolchain and toolchain to variant 190 toolchain_to_variant_dict = platform_loader.platforms_toolchain() 191 toolchain_variant_info_file = os.path.join(source_root_dir, 192 config_output_relpath, 193 platforms_info_output_dir, 194 "toolchain_to_variant.json") 195 write_json_file(toolchain_variant_info_file, 196 toolchain_to_variant_dict, 197 check_changes=True) 198 199 result = {} 200 result['all_parts'] = all_parts 201 result['all_stubs'] = platform_loader.get_all_stubs() 202 result['variant_toolchain_info'] = toolchain_to_variant_dict 203 return result 204