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