• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#coding=utf-8
3
4#
5# Copyright (c) 2022 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#
18
19import os
20import json
21
22from .base_rule import BaseRule
23
24class ChipsetSDKRule(BaseRule):
25    RULE_NAME = "ChipsetSDK"
26
27    def __init__(self, mgr, args):
28        super().__init__(mgr, args)
29        self.__out_path = mgr.get_product_out_path()
30        self.__white_lists = self.load_chipsetsdk_json("chipsetsdk_info.json")
31
32    def get_white_lists(self):
33        return self.__white_lists
34
35    def get_out_path(self):
36        return self.__out_path
37
38    def load_chipsetsdk_json(self, name):
39        rules_dir = []
40        rules_dir.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../rules"))
41        if self._args and self._args.rules:
42            self.log("****add more ChipsetSDK info in:{}****".format(self._args.rules))
43            rules_dir = rules_dir + self._args.rules
44
45        chipsetsdk_rules_path = self.get_out_path().replace("out", "out/products_ext")
46        if os.path.exists(chipsetsdk_rules_path):
47            self.log("****add more ChipsetSDK info in dir:{}****".format(chipsetsdk_rules_path))
48            rules_dir.append(chipsetsdk_rules_path)
49        else:
50            self.warn("****add chipsetsdk_rules_path path not exist: {}****".format(chipsetsdk_rules_path))
51        res = []
52        for d in rules_dir:
53            rules_file = os.path.join(d, self.__class__.RULE_NAME, name)
54            if os.path.isfile(rules_file):
55                res = self.__parser_rules_file(rules_file, res)
56            else:
57                self.warn("****rules path not exist: {}****".format(rules_file))
58
59        return res
60
61    def __parser_rules_file(self, rules_file, res):
62            try:
63                self.log("****Parsing rules file in {}****".format(rules_file))
64                with open(rules_file, "r") as f:
65                    contents = f.read()
66                if not contents:
67                    self.log("****rules file {} is null****".format(rules_file))
68                    return res
69                json_data = json.loads(contents)
70                for so in json_data:
71                    so_file_name = so.get("so_file_name")
72                    if so_file_name and so_file_name not in res:
73                        res.append(so_file_name)
74            except(FileNotFoundError, IOError, UnicodeDecodeError) as file_open_or_decode_err:
75                self.error(file_open_or_decode_err)
76
77            return res
78
79    def __is_chipsetsdk_tagged(self, mod):
80        if not "innerapi_tags" in mod:
81            return False
82        if "chipsetsdk" in mod["innerapi_tags"]:
83            return True
84        return False
85
86    def __is_chipsetsdk_indirect(self, mod):
87        if not "innerapi_tags" in mod:
88            return False
89        if "chipsetsdk_indirect" in mod["innerapi_tags"]:
90            return True
91        return False
92
93    def __write_innerkits_header_files(self):
94        inner_kits_info = os.path.join(self.get_mgr().get_product_out_path(),
95                                       "build_configs/parts_info/inner_kits_info.json")
96        with open(inner_kits_info, "r") as f:
97            info = json.load(f)
98
99        headers = []
100        for sdk in self.__chipsetsdks:
101            path = sdk["labelPath"][:sdk["labelPath"].find(":")]
102            target_name = sdk["labelPath"][sdk["labelPath"].find(":") + 1:]
103            item = {"name": sdk["componentName"] + ":" + target_name, "so_file_name":
104                    sdk["name"], "path": sdk["labelPath"], "headers": []}
105            if sdk["componentName"] not in info:
106                headers.append(item)
107                continue
108
109            for name, innerapi in info[sdk["componentName"]].items():
110                if innerapi["label"] != sdk["labelPath"]:
111                    continue
112                gotHeaders = True
113                base = innerapi["header_base"]
114                for f in innerapi["header_files"]:
115                    item["headers"].append(os.path.join(base, f))
116            headers.append(item)
117
118        try:
119            with open(os.path.join(self.get_mgr().get_product_images_path(), "chipsetsdk_info.json"), "w") as f:
120                json.dump(headers, f, indent = 4)
121        except:
122            pass
123
124        return headers
125
126    def __check_chipsetsdk_indirect(self):
127        passed = True
128        for mod in self.__chipsetsdks:
129            for dep in mod["deps"]:
130                callee = dep["callee"]
131
132                # Chipset SDK is OK
133                if callee["name"] in self.get_white_lists():
134                    continue
135
136                # chipsetsdk_indirect module is OK
137                if self.__is_chipsetsdk_indirect(callee) or callee["name"] in self.__indirects:
138                    continue
139
140                # Not correct
141                passed = False
142                self.error('Chipset SDK module %s should not depends on non Chipset SDK module \
143                           %s in %s with "chipsetsdk_indirect"' % (mod["name"], callee["name"], callee["labelPath"]))
144
145        return passed
146
147    def __check_depends_on_chipsetsdk(self):
148        lists = self.get_white_lists()
149
150        passed = True
151
152        self.__chipsetsdks = []
153        self.__modules_with_chipsetsdk_tag = []
154        self.__modules_with_chipsetsdk_indirect_tag = []
155
156        # Check if any napi modules has dependedBy
157        for mod in self.get_mgr().get_all():
158            # Collect all modules with chipsetsdk tag
159            if self.__is_chipsetsdk_tagged(mod):
160                self.__modules_with_chipsetsdk_tag.append(mod)
161
162            # Collect all modules with chipsetsdk_indirect tag
163            if self.__is_chipsetsdk_indirect(mod):
164                self.__modules_with_chipsetsdk_indirect_tag.append(mod)
165
166            # Check chipset modules only
167            if mod["path"].startswith("system"):
168                continue
169
170            # Check chipset modules depends
171            for dep in mod["deps"]:
172                callee = dep["callee"]
173
174                # If callee is chipset module, it is OK
175                if not callee["path"].startswith("system"):
176                    continue
177
178                # Add to list
179                if callee not in self.__chipsetsdks:
180                    if "hdiType" not in callee or callee["hdiType"] != "hdi_proxy":
181                        self.__chipsetsdks.append(callee)
182
183                # If callee is in Chipset SDK white list module, it is OK
184                if callee["name"] in lists:
185                    continue
186
187                # If callee is asan library, it is OK
188                if callee["name"].endswith(".asan.so"):
189                    continue
190
191                # If callee is hdi proxy module, it is OK
192                if "hdiType" in callee and callee["hdiType"] == "hdi_proxy":
193                    continue
194
195                # Not allowed
196                passed = False
197                self.error("chipset module %s depends on non Chipset SDK module %s in %s"
198                           % (mod["name"], callee["name"], mod["labelPath"]))
199
200        return passed
201
202
203    def __check_if_tagged_correctly(self):
204        passed = True
205        for mod in self.__chipsetsdks:
206            if not self.__is_chipsetsdk_tagged(mod):
207                self.warn('Chipset SDK module %s has no innerapi_tags with "chipsetsdk", add it in %s'
208                          % (mod["name"], mod["labelPath"]))
209
210        for mod in self.__modules_with_chipsetsdk_tag:
211            if mod["name"] not in self.get_white_lists():
212                passed = False
213                self.error('non chipsetsdk module %s with innerapi_tags="chipsetsdk", %s'
214                           % (mod["name"], mod["labelPath"]))
215
216        for mod in self.__modules_with_chipsetsdk_indirect_tag:
217            if mod["name"] not in self.__indirects and mod["name"] not in self.get_white_lists():
218                self.warn('non chipsetsdk_indirect module %s with innerapi_tags="chipsetsdk_indirect", %s'
219                          % (mod["name"], mod["labelPath"]))
220
221        return passed
222
223    def __load_chipsetsdk_indirects(self):
224        self.__indirects = self.load_chipsetsdk_json("chipsetsdk_indirect.json")
225
226    def check(self):
227        self.__load_chipsetsdk_indirects()
228
229        # Check if all chipset modules depends on chipsetsdk modules only
230        passed = self.__check_depends_on_chipsetsdk()
231        if not passed:
232            return passed
233
234        # Check if all chipsetsdk module depends on chipsetsdk or chipsetsdk_indirect modules only
235        passed = self.__check_chipsetsdk_indirect()
236        if not passed:
237            return passed
238
239        # Check if all ChipsetSDK modules are correctly tagged by innerapi_tags
240        passed = self.__check_if_tagged_correctly()
241        if not passed:
242            return passed
243
244        self.__write_innerkits_header_files()
245
246        return True
247