• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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