1#!/usr/bin/env python3 2# coding=utf-8 3# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 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 16""" 17* Description: Utilities of compile system. 18* Create: 2020-1-2 19""" 20 21import os 22import sys 23import stat 24import time 25import subprocess 26import re 27import shutil 28import logging 29 30""" 31Colors defines. To highlight important output. 32""" 33__colors__ = {'purple':'\033[95m', 'red':'\033[91m', 'blue':'\033[94m', 'green':'\033[92m', 'end':'\033[0m'} 34 35""" 36Error handling, highlight in red. 37""" 38class BuildError(Exception): 39 def __init__(self, err): 40 emsg = "%s%s%s"%(color_red(), err, color_end()) 41 Exception.__init__(self, emsg) 42 43# End of class BuildError 44 45""" 46timer 47""" 48class BuildTimer: 49 def __init__(self, name='A'): 50 self._start = -1 51 self._name = name 52 53 def start(self): 54 self._start = time.time() 55 56 def stop(self): 57 if self._start == -1: 58 raise BuildError("Timer %s never been started!"%self._name) 59 retval = time.time() - self._start 60 self._start = -1 61 return retval 62# End of class BuildTimer 63 64def color_red(): 65 return __colors__.get('red') 66 67def color_purple(): 68 return __colors__.get('purple') 69 70def color_blue(): 71 return __colors__.get('blue') 72 73def color_green(): 74 return __colors__.get('green') 75 76def color_end(): 77 return __colors__.get('end') 78 79def print_info(msg): 80 print(msg) 81 82def print_tips(msg): 83 print("%s%s%s"%(color_purple(), msg, color_end())) 84 85def print_warning(msg): 86 print("%s%s%s"%(color_green(), msg, color_end())) 87 88def print_alert(msg): 89 print("%s%s%s"%(color_red(), msg, color_end())) 90 91def fn_filter_dirs(dirs, filters=[]): 92 retval = list(dirs) 93 for dir_path in dirs: 94 for item in filters: 95 fstr = "%s%s%s"%(os.sep, item, os.sep) 96 if (dir_path.find(fstr) >= 0): 97 try: 98 print("remove dir_path:%s" % dir_path) 99 retval.remove(dir_path) 100 except ValueError as e: 101 print(e) 102 103 return retval 104 105def fn_search_all_files(top_dir, file_name, excludes=[]): 106 """ 107 Traverse sub-folders to find all files named "file_name". 108 """ 109 retval = [] 110 for dir_path, dir_names, file_names in os.walk(top_dir, followlinks=True): 111 # remove useless folder first 112 dir_names = [dir_names.remove(x) for x in dir_names if x.startswith(".")] 113 if file_name in file_names: 114 retval.append(os.path.join(dir_path, file_name)) 115 return fn_filter_dirs(retval, excludes) 116 117def fn_search_all_dirs(top_dir, dir_name, excludes=[]): 118 """ 119 Traverse sub-folders to find all files named "dir_name". 120 """ 121 retval = [] 122 for dir_path, dir_names, file_names in os.walk(top_dir, followlinks=True): 123 if not dir_names: 124 continue 125 # remove useless folder first 126 temp_dirs = list(dir_names) 127 dirnames = [x for x in dir_names if not x.startswith(".")] 128 for dirname in dirnames: 129 if dirname and dirname == dir_name: 130 retval.append(os.path.join(dir_path, dirname)) 131 return fn_filter_dirs(retval, excludes) 132 133def fn_get_subdirs(dir_path): 134 lst = [name for name in os.listdir(dir_path) if os.path.isdir(os.path.join(dir_path, name)) and name[0] != '.'] 135 lst.sort() 136 return lst 137 138def fn_str_to_int(text, num=None): 139 if num is not None: 140 return int(text, num) 141 match1 = re.match(r'\s*0x',text) 142 match2 = re.match(r'\s*0X',text) 143 if match1 or match2: 144 return int(text, 16) 145 else: 146 return int(text, 10) 147 148""" 149Convert build error from scons to string. 150""" 151def bf_to_str(bf): 152 if bf is None: 153 return '(unknown targets product None in list)' 154 elif bf.node: 155 return str(bf.node) + ': ' + bf.errstr 156 elif bf.filename: 157 return bf.filename + ': ' + bf.errstr 158 else: 159 return str(bf) 160 161""" 162call shell 163""" 164def exec_shell(cmd, logfile=None): 165 cmdlist = cmd 166 logfp = None 167 if isinstance(cmd, str): 168 cmdlist = cmd.split(' ') 169 170 logger = logging.getLogger() 171 logger.setLevel(logging.INFO) 172 if not logger.handlers: 173 logger.addHandler(logging.StreamHandler(sys.stdout)) 174 175 if logfile: 176 if os.path.isfile(logfile): 177 os.unlink(logfile) 178 if len(logger.handlers) < 2: # 1. console; 2. file 179 logfp = logging.FileHandler(logfile, encoding='utf-8') 180 logger.addHandler(logfp) 181 try: 182 logging.info(str(cmdlist)) 183 logging.info('\n') 184 subp = subprocess.Popen(cmdlist, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 185 while True: 186 try: 187 output = subp.stdout.readline() 188 output = output.decode(encoding='UTF-8', errors='replace') 189 if output == '' and subp.poll() is not None: 190 break 191 if output: 192 logging.info(output.strip()) 193 except UnicodeDecodeError as err: 194 pass 195 return subp.returncode 196 except FileNotFoundError as err: 197 logging.error(err) 198 raise Exception(err) 199 except Exception as err: 200 logging.error(err) 201 raise Exception(err) 202 finally: 203 if logfile and logfp: 204 logfp.close() 205 206def add_temp_sys_path(path): 207 env_path = os.environ.get('PATH') 208 if path.startswith(os.sep): 209 work_path = path 210 else: 211 work_path = os.path.join(os.getcwd(), path) 212 213 if work_path not in env_path: 214 new_env_path = ':'.join([work_path, env_path]) 215 os.environ['PATH'] = new_env_path 216 return os.environ.get('PATH') 217 218def rm_all(items): 219 for item in items: 220 if os.path.isdir(item): 221 shutil.rmtree(item) 222 elif os.path.isfile(item): 223 os.unlink(item) 224 else: 225 pass 226 227def rm_pyc(root): 228 pyc_dirs = fn_search_all_dirs(root, "__pycache__") 229 rm_all(pyc_dirs) 230 231def get_diff(list0, list1): 232 diff = list(set(list0) - set(list1)) 233 return diff 234 235