• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4#
5# Copyright (c) 2020 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 platform
20from distutils.spawn import find_executable
21
22from hb_internal import CONFIG_JSON
23from hb_internal import CONFIG_STRUCT
24from hb_internal import BUILD_TOOLS_CFG
25from hb_internal.common.utils import read_json_file
26from hb_internal.common.utils import dump_json_file
27from hb_internal.common.utils import Singleton
28from hb_internal.common.utils import OHOSException
29from hb_internal.common.utils import download_tool
30from hb_internal.common.utils import makedirs
31
32
33class Config(metaclass=Singleton):
34    def __init__(self):
35        self.config_json = CONFIG_JSON
36
37        config_content = read_json_file(self.config_json)
38        self._root_path = config_content.get('root_path', None)
39        self._board = config_content.get('board', None)
40        self._kernel = config_content.get('kernel', None)
41        self._product = config_content.get('product', None)
42        self._product_path = config_content.get('product_path', None)
43        self._device_path = config_content.get('device_path', None)
44        self._device_company = config_content.get('device_company', None)
45        self._patch_cache = config_content.get('patch_cache', None)
46        self._version = config_content.get('version', '3.0')
47        self._os_level = config_content.get('os_level', 'small')
48        self._product_json = config_content.get('product_json', None)
49        self._target_cpu = config_content.get('target_cpu', None)
50        self._target_os = config_content.get('target_os', None)
51        self._out_path = config_content.get('out_path', None)
52        self.fs_attr = set()
53        self.platform = platform.system()
54
55    @property
56    def target_os(self):
57        return self._target_os
58
59    @target_os.setter
60    def target_os(self, value):
61        self._target_os = value
62        self.config_update('target_os', self._target_os)
63
64    @property
65    def target_cpu(self):
66        return self._target_cpu
67
68    @target_cpu.setter
69    def target_cpu(self, value):
70        self._target_cpu = value
71        self.config_update('target_cpu', self._target_cpu)
72
73    @property
74    def version(self):
75        return self._version
76
77    @version.setter
78    def version(self, value):
79        self._version = value
80        self.config_update('version', self._version)
81
82    @property
83    def os_level(self):
84        return self._os_level
85
86    @os_level.setter
87    def os_level(self, value):
88        self._os_level = value
89        self.config_update('os_level', self._os_level)
90
91    @property
92    def product_json(self):
93        return self._product_json
94
95    @product_json.setter
96    def product_json(self, value):
97        self._product_json = value
98        self.config_update('product_json', self._product_json)
99
100    @property
101    def root_path(self):
102        if self._root_path is None:
103            raise OHOSException('Failed to get root_path. '
104                                'Please run command "hb set" to '
105                                'init OHOS development environment')
106
107        return self._root_path
108
109    @root_path.setter
110    def root_path(self, value):
111        self._root_path = os.path.abspath(value)
112        if not os.path.isdir(self._root_path):
113            raise OHOSException(f'{self._root_path} is not a valid path')
114
115        config_path = os.path.join(self._root_path, 'ohos_config.json')
116        if not os.path.isfile(config_path):
117            self.config_create(config_path)
118        self.config_update('root_path', self._root_path)
119
120    @property
121    def board(self):
122        if self._board is None:
123            raise OHOSException('Failed to get board. '
124                                'Please run command "hb set" to '
125                                'init OHOS development environment')
126        return self._board
127
128    @board.setter
129    def board(self, value):
130        self._board = value
131        self.config_update('board', self._board)
132
133    @property
134    def device_company(self):
135        if self._device_company is None:
136            raise OHOSException('Failed to get device_company. '
137                                'Please run command "hb set" to '
138                                'init OHOS development environment')
139        return self._device_company
140
141    @device_company.setter
142    def device_company(self, value):
143        self._device_company = value
144        self.config_update('device_company', self._device_company)
145
146    @property
147    def kernel(self):
148        return self._kernel
149
150    @kernel.setter
151    def kernel(self, value):
152        self._kernel = value
153        self.config_update('kernel', self._kernel)
154
155    @property
156    def product(self):
157        if self._product is None:
158            raise OHOSException('Failed to get product. '
159                                'Please run command "hb set" to '
160                                'init OHOS development environment')
161        return self._product
162
163    @product.setter
164    def product(self, value):
165        self._product = value
166        self.config_update('product', self._product)
167
168    @property
169    def product_path(self):
170        if self._product_path is None:
171            raise OHOSException('Failed to get product_path. '
172                                'Please run command "hb set" to '
173                                'init OHOS development environment')
174        return self._product_path
175
176    @product_path.setter
177    def product_path(self, value):
178        self._product_path = value
179        self.config_update('product_path', self._product_path)
180
181    @property
182    def gn_product_path(self):
183        return self.product_path.replace(self.root_path, '/')
184
185    @property
186    def device_path(self):
187        if self._device_path is None:
188            raise OHOSException('Failed to get device_path. '
189                                'Please run command "hb set" to '
190                                'init OHOS development environment')
191        return self._device_path
192
193    @device_path.setter
194    def device_path(self, value):
195        self._device_path = value
196        self.config_update('device_path', self._device_path)
197
198    @property
199    def gn_device_path(self):
200        return self.device_path.replace(self.root_path, '/')
201
202    @property
203    def build_path(self):
204        _build_path = os.path.join(self.root_path, 'build', 'lite')
205        if not os.path.isdir(_build_path):
206            raise OHOSException(f'Invalid build path: {_build_path}')
207        return _build_path
208
209    @property
210    def out_path(self):
211        return self._out_path
212
213    @out_path.setter
214    def out_path(self, value):
215        self._out_path = value
216        self.config_update('out_path', self._out_path)
217
218    @property
219    def log_path(self):
220        if self.out_path is not None:
221            return os.path.join(self.out_path, 'build.log')
222        else:
223            raise OHOSException(f'Failed to get log_path')
224
225    @property
226    def vendor_path(self):
227        _vendor_path = os.path.join(self.root_path, 'vendor')
228        if not os.path.isdir(_vendor_path):
229            raise OHOSException(f'Invalid vendor path: {_vendor_path}')
230        return _vendor_path
231
232    @property
233    def built_in_product_path(self):
234        _built_in_product_path = os.path.join(self.root_path,
235                                              'productdefine/common/products')
236        if not os.path.isdir(_built_in_product_path):
237            raise OHOSException(
238                f'Invalid built-in product path: {_built_in_product_path}')
239        return _built_in_product_path
240
241    @property
242    def built_in_device_path(self):
243        _built_in_device_path = os.path.join(self.root_path,
244                                             'productdefine/common/device')
245        if not os.path.isdir(_built_in_device_path):
246            raise OHOSException(
247                f'Invalid built-in product path: {_built_in_device_path}')
248        return _built_in_device_path
249
250    @property
251    def build_tools_path(self):
252        try:
253            tools_path = BUILD_TOOLS_CFG[self.platform]['build_tools_path']
254            return os.path.join(self.root_path, tools_path)
255        except KeyError:
256            raise OHOSException(f'unidentified platform: {self.platform}')
257
258    @property
259    def gn_path(self):
260        repo_gn_path = os.path.join(self.build_tools_path, 'gn')
261        # gn exist.
262        if os.path.isfile(repo_gn_path):
263            return repo_gn_path
264
265        # gn not install, download and extract it.
266        makedirs(self.build_tools_path, exist_ok=True)
267
268        gn_url = BUILD_TOOLS_CFG[self.platform].get('gn')
269        gn_dst = os.path.join(self.build_tools_path, 'gn_pkg')
270        download_tool(gn_url, gn_dst, tgt_dir=self.build_tools_path)
271
272        return repo_gn_path
273
274    @property
275    def ninja_path(self):
276        repo_ninja_path = os.path.join(self.build_tools_path, 'ninja')
277        # ninja exist.
278        if os.path.isfile(repo_ninja_path):
279            return repo_ninja_path
280
281        # ninja not install, download and extract.
282        makedirs(self.build_tools_path, exist_ok=True)
283
284        ninja_url = BUILD_TOOLS_CFG[self.platform].get('ninja')
285        ninja_dst = os.path.join(self.build_tools_path, 'ninja_pkg')
286        download_tool(ninja_url, ninja_dst, tgt_dir=self.build_tools_path)
287
288        return repo_ninja_path
289
290    @property
291    def clang_path(self):
292        repo_clang_path = os.path.join('prebuilts', 'clang', 'ohos',
293                                       'linux-x86_64', 'llvm')
294        # clang exist
295        if os.path.isdir(repo_clang_path):
296            return f'//{repo_clang_path}'
297        # clang installed manually or auto download
298        else:
299            # already installed manually
300            env_clang_bin_path = find_executable('clang')
301            if env_clang_bin_path is not None:
302                env_clang_path = os.path.abspath(
303                    os.path.join(env_clang_bin_path, os.pardir, os.pardir))
304
305                if os.path.basename(env_clang_path) == 'llvm':
306                    return env_clang_path
307
308            # need auto download and extract clang.
309            clang_path = os.path.abspath(
310                os.path.join(repo_clang_path, os.pardir))
311            makedirs(clang_path, exist_ok=True)
312
313            clang_url = BUILD_TOOLS_CFG[self.platform].get('clang')
314            clang_dst = os.path.join(clang_path, 'clang_pkg')
315            download_tool(clang_url, clang_dst, tgt_dir=clang_path)
316            return f'//{repo_clang_path}'
317
318    @property
319    def patch_cache(self):
320        return self._patch_cache
321
322    @patch_cache.setter
323    def patch_cache(self, value):
324        self._patch_cache = value
325        self.config_update('patch_cache', self._patch_cache)
326
327    def config_create(self, config_path):
328        dump_json_file(config_path, CONFIG_STRUCT)
329        self.config_json = config_path
330
331    def config_update(self, key, value):
332        config_content = read_json_file(self.config_json)
333        config_content[key] = value
334        dump_json_file(self.config_json, config_content)
335