• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4#
5# Copyright (c) 2023 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18import os
19import stat
20
21from services.interface.preload_interface import PreloadInterface
22from util.io_util import IoUtil
23from util.preloader.preloader_process_data import Dirs, Outputs, Product
24from util.preloader.parse_lite_subsystems_config import parse_lite_subsystem_config
25from util.log_util import LogUtil
26
27
28class OHOSPreloader(PreloadInterface):
29
30    def __init__(self):
31        super().__init__()
32        self._dirs = ""
33        self._outputs = ""
34        self._product = ""
35        self._os_level = ""
36        self._target_cpu = ""
37        self._target_os = ""
38        self._toolchain_label = ""
39        self._subsystem_info = {}
40        self._all_parts = {}
41        self._build_vars = {}
42        self._compile_standard_whitelist_info = {}
43        self._compile_env_allowlist_info = {}
44
45    def __post_init__(self):
46        self._dirs = Dirs(self._config)
47        self._outputs = Outputs(self._dirs.preloader_output_dir)
48        self._product = Product(self._dirs, self._config)
49        self._all_parts = self._product._parts
50        self._build_vars = self._product._build_vars
51        self._os_level = self._build_vars.get('os_level')
52        self._target_os = self._build_vars.get('target_os')
53        self._target_cpu = self._build_vars.get('target_cpu')
54        self._toolchain_label = self._build_vars.get('product_toolchain_label')
55        self._subsystem_info = self._get_org_subsystem_info()
56        self._compile_standard_whitelist_info = self._get_compile_standard_whitelist_info()
57        self._compile_env_allowlist_info = self._get_compile_env_allowlist_info()
58
59# generate method
60
61    '''Description: generate platforms build info to "out/preloader/{product_name}/platforms.build"
62    @parameter:none
63    @return :none
64    '''
65
66    def _generate_platforms_build(self):
67        config = {
68            'target_os': self._target_os,
69            "target_cpu": self._target_cpu,
70            "toolchain": self._toolchain_label,
71            "parts_config": os.path.relpath(self._outputs.parts_json,
72                                            self._dirs.preloader_output_dir)
73        }
74        platform_config = {'version': 2, 'platforms': {'phone': config}}
75        IoUtil.dump_json_file(self._outputs.platforms_build, platform_config)
76        LogUtil.hb_info(
77            'generated platforms build info to {}/platforms.build'.format(
78                self._dirs.preloader_output_dir), mode=self.config.log_mode)
79
80    '''Description: generate build gnargs prop info to "out/preloader/{product_name}/build_gnargs.prop"
81    @parameter:none
82    @return :none
83    '''
84
85    def _generate_build_gnargs_prop(self):
86        all_features = {}
87        for _part_name, vals in self._all_parts.items():
88            _features = vals.get('features')
89            if _features:
90                all_features.update(_features)
91        attr_list = []
92        for key, val in all_features.items():
93            _item = ''
94            if isinstance(val, bool):
95                _item = f'{key}={str(val).lower()}'
96            elif isinstance(val, int):
97                _item = f'{key}={val}'
98            elif isinstance(val, str):
99                _item = f'{key}="{val}"'
100            else:
101                raise Exception("part feature '{key}:{val}' type not support.")
102            attr_list.append(_item)
103        with os.fdopen(os.open(self._outputs.build_gnargs_prop,
104                               os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj:
105            fobj.write('\n'.join(attr_list))
106        LogUtil.hb_info(
107            'generated build gnargs prop info to {}/build_gnargs.prop'.format(
108                self._dirs.preloader_output_dir), mode=self.config.log_mode)
109
110    '''Description: generate features to "out/preloader/{product_name}/features.json"
111    @parameter:none
112    @return :none
113    '''
114
115    def _generate_features_json(self):
116        all_features = {}
117        part_feature_map = {}
118        for _part_name, vals in self._all_parts.items():
119            _features = vals.get('features')
120            if _features:
121                all_features.update(_features)
122            if _features:
123                part_feature_map[_part_name.split(
124                    ':')[1]] = list(_features.keys())
125        parts_feature_info = {
126            "features": all_features,
127            "part_to_feature": part_feature_map
128        }
129        IoUtil.dump_json_file(self._outputs.features_json, parts_feature_info)
130        LogUtil.hb_info(
131            'generated features info to {}/features.json'.format(
132                self._dirs.preloader_output_dir), mode=self.config.log_mode)
133
134    '''Description: generate syscap to "out/preloader/product_name/syscap.json"
135    @parameter:none
136    @return :none
137    '''
138
139    def _generate_syscap_json(self):
140        all_syscap = {}
141        part_syscap_map = {}
142        for _part_name, vals in self._all_parts.items():
143            _syscap = vals.get('syscap')
144            if _syscap:
145                all_syscap.update(_syscap)
146                part_syscap_map[_part_name.split(':')[1]] = _syscap
147        parts_syscap_info = {
148            "syscap": all_syscap,
149            "part_to_syscap": part_syscap_map
150        }
151        IoUtil.dump_json_file(self._outputs.syscap_json, parts_syscap_info)
152        LogUtil.hb_info(
153            'generated syscap info to {}/syscap.json'.format(
154                self._dirs.preloader_output_dir), mode=self.config.log_mode)
155
156    '''Description: generate exclusion modules info to "out/preloader/product_name/exclusion_modules.json"
157    @parameter:none
158    @return :none
159    '''
160
161    def _generate_exclusion_modules_json(self):
162        exclusions = {}
163        for _part_name, vals in self._all_parts.items():
164            _exclusions = vals.get('exclusions')
165            if _exclusions:
166                pair = dict()
167                pair[_part_name] = _exclusions
168                exclusions.update(pair)
169        IoUtil.dump_json_file(self._outputs.exclusion_modules_json, exclusions)
170        LogUtil.hb_info(
171            'generated exclusion modules info to {}/exclusion_modules.json'.format(
172                self._dirs.preloader_output_dir), mode=self.config.log_mode)
173
174    '''Description: generate build config info to "out/preloader/product_name/build_config.json"
175    @parameter:none
176    @return :none
177    '''
178
179    def _generate_build_config_json(self):
180        IoUtil.dump_json_file(
181            self._outputs.build_config_json, self._build_vars)
182        LogUtil.hb_info(
183            'generated build config info to {}/build_config.json'.format(
184                self._dirs.preloader_output_dir), mode=self.config.log_mode)
185
186    '''Description: generate build prop info to "out/preloader/product_name/build.prop"
187    @parameter:none
188    @return :none
189    '''
190
191    def _generate_build_prop(self):
192        build_vars_list = []
193        for key, value in self._build_vars.items():
194            build_vars_list.append('{}={}'.format(key, value))
195        with os.fdopen(os.open(self._outputs.build_prop,
196                               os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 'w') as fobj:
197            fobj.write('\n'.join(build_vars_list))
198        LogUtil.hb_info(
199            'generated build prop info to {}/build.prop'.format(
200                self._dirs.preloader_output_dir), mode=self.config.log_mode)
201
202    '''Description: generate parts to "out/preloader/product_name/parts.json"
203    @parameter:none
204    @return :none
205    '''
206
207    def _generate_parts_json(self):
208        parts_info = {"parts": sorted(list(self._all_parts.keys()))}
209        IoUtil.dump_json_file(self._outputs.parts_json, parts_info)
210        LogUtil.hb_info(
211            'generated product parts info to {}/parts.json'.format(
212                self._dirs.preloader_output_dir), mode=self.config.log_mode)
213
214    '''Description: generate parts config to "out/preloader/product_name/parts_config.json"
215    @parameter:none
216    @return :none
217    '''
218
219    def _generate_parts_config_json(self):
220        parts_config = {}
221        for part in self._all_parts:
222            part = part.replace(":", "_")
223            part = part.replace("-", "_")
224            part = part.replace(".", "_")
225            part = part.replace("/", "_")
226            parts_config[part] = True
227        IoUtil.dump_json_file(self._outputs.parts_config_json, parts_config)
228        LogUtil.hb_info(
229            'generated parts config info to {}/parts_config.json'.format(
230                self._dirs.preloader_output_dir), mode=self.config.log_mode)
231
232    '''Description: generate subsystem config info to "out/preloader/product_name/subsystem_config.json"
233    @parameter:none
234    @return :none
235    '''
236
237    def _generate_subsystem_config_json(self):
238        if self._subsystem_info:
239            self._subsystem_info.update(
240                self._product._get_product_specific_subsystem())
241            self._subsystem_info.update(
242                self._product._get_device_specific_subsystem())
243        IoUtil.dump_json_file(
244            self._outputs.subsystem_config_json, self._subsystem_info)
245        LogUtil.hb_info(
246            'generated subsystem config info to {}/subsystem_config.json'.format(
247                self._dirs.preloader_output_dir), mode=self.config.log_mode)
248
249    '''Description: generate systemcapability_json to "out/preloader/product_name/systemcapability.json"
250    @parameter:none
251    @return :none
252    '''
253
254    def _generate_systemcapability_json(self):
255        IoUtil.dump_json_file(
256            self._outputs.systemcapability_json, self._product._syscap_info)
257        LogUtil.hb_info(
258            'generated system capability info to {}/systemcapability.json'.format(
259                self._dirs.preloader_output_dir), mode=self.config.log_mode)
260
261    '''Description: generate compile_standard_whitelist info  to "out/preloader/product_name/compile_standard_whitelist.json"
262    @parameter:none
263    @return :none
264    '''
265
266    def _generate_compile_standard_whitelist_json(self):
267        IoUtil.dump_json_file(
268            self._outputs.compile_standard_whitelist_json, self._compile_standard_whitelist_info)
269        LogUtil.hb_info(
270            'generated compile_standard_whitelist info to {}/compile_standard_whitelist.json'
271            .format(self._dirs.preloader_output_dir), mode=self.config.log_mode)
272
273    def _generate_compile_env_allowlist_json(self):
274        IoUtil.dump_json_file(
275            self._outputs.compile_env_allowlist_json, self._compile_env_allowlist_info
276        )
277        LogUtil.hb_info(
278            "generated compile_env_allowlist info to {}/compile_env_allowlist.json".format(
279                self._dirs.preloader_output_dir
280            )
281        )
282
283# get method
284
285    def _get_org_subsystem_info(self) -> dict:
286        subsystem_info = {}
287        if self._os_level == "standard":
288            subsystem_info = IoUtil.read_json_file(
289                self._dirs.subsystem_config_json)
290        elif self._os_level == "mini" or self._os_level == "small":
291            ohos_build_output_dir = os.path.join(self._dirs.preloader_output_dir,
292                                                 '{}_system'.format(self._os_level))
293            subsystem_info = parse_lite_subsystem_config(
294                self._dirs.lite_components_dir, ohos_build_output_dir,
295                self._dirs.source_root_dir, self._dirs.subsystem_config_json)
296        return subsystem_info
297
298    def _get_compile_standard_whitelist_info(self) -> dict:
299        allow_info_file = "out/products_ext/{}/compile_standard_whitelist.json".format(self.config.product)
300        allow_info_file = os.path.join(self._dirs.source_root_dir, allow_info_file)
301        if not os.path.exists(allow_info_file):
302            allow_info_file = os.path.join(self._dirs.source_root_dir, "build/compile_standard_whitelist.json")
303
304        allow_info = IoUtil.read_json_file(allow_info_file)
305        return allow_info
306
307    def _get_compile_env_allowlist_info(self) -> dict:
308        allow_env_file = os.path.join(
309            self._dirs.source_root_dir,
310            "out/products_ext/{}/compile_env_allowlist.json".format(
311                self.config.product
312            ),
313        )
314        if not os.path.exists(allow_env_file):
315            allow_env_file = os.path.join(
316                self._dirs.source_root_dir, "build/compile_env_allowlist.json"
317            )
318
319        if not os.path.exists(allow_env_file):
320            return {}
321
322        allow_env = IoUtil.read_json_file(allow_env_file)
323        return allow_env
324