1#!/usr/bin/env python3 2# coding=utf-8 3 4''' 5* Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 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* Description: Utilities. 19''' 20 21import os 22import shutil 23from copy import deepcopy 24 25from hi_config_parser import usr_cfg_main 26from hi_config_parser import sys_cfg_main 27 28class SconsBuildError(Exception): 29 """ 30 Error exception. 31 """ 32 pass 33 34""" 35Colors to display the messages. 36""" 37colors = {} 38colors['cyan'] = '\033[96m' 39colors['purple'] = '\033[95m' 40colors['blue'] = '\033[94m' 41colors['green'] = '\033[92m' 42colors['yellow'] = '\033[93m' 43colors['red'] = '\033[91m' 44colors['end'] = '\033[0m' 45 46flag = { 47 'ARFLAGS' : 'ar_flags', 48 'CCFLAGS' : 'opts', #'cc_flags', 49 'ASLAGS' : 'as_flags', 50 'CPPDEFINES' : 'defines', 51 'CPPPATH' : ['liteos_inc_path', 'common_inc_path'], 52 'LINKFLAGS' : 'link_flags', 53 'LINK_SCRIPTS_FLAG' : 'link_scripts_flag' 54} 55 56flag_r = { 57 'ar_flags' : 'ARFLAGS', 58 'opts' : 'CCFLAGS', 59 'as_flags' : 'ASLAGS', 60 'defines' : 'CPPDEFINES', 61 'liteos_inc_path' : 'CPPPATH', 62 'common_inc_path' : 'CPPPATH', 63 'link_flags' : 'LINKFLAGS', 64 'link_scripts_flag' : 'LINK_SCRIPTS_FLAG' 65} 66 67def traverse_subdir(search_dir = '.', full_path = False): 68 src_path = [] 69 for root, dirs, files in os.walk(search_dir): 70 if files != []: 71 src_path.append(os.path.relpath(root, search_dir)) if full_path == False else src_path.append(root) 72 print('relative dir:',os.path.relpath(root, search_dir) if full_path == False else root) 73 return src_path 74 75#compiler check 76def scons_env_param_check(): 77 env_path_param = os.environ['PATH'].split(':') 78 for param in env_path_param: 79 compiler = os.path.join(param, 'riscv32-unknown-elf-gcc') 80 if os.path.isfile(compiler): 81 return True 82 return False 83 84#settings check 85def scons_pre_check(dir_list): 86 if len(dir_list) > 0 : 87 for dir in dir_list: 88 os.makedir(dir) 89 usr_config_path = os.path.join('build', 'config', 'usr_config.mk') 90 if os.path.isfile(usr_config_path) == False: 91 shutil.copyfile(os.path.join('tools', 'menuconfig', 'default.config'), usr_config_path) 92 return scons_env_param_check() 93 94#delete files while compiling. 95def cleanup(target, source, env): 96 for src in source: 97 name = str(src) 98 try: 99 if os.path.isfile(name): 100 os.remove(name) 101 elif os.path.isdir(name): 102 shutil.rmtree(name) 103 else: 104 print("%s not found! Skipped!"%src) 105 except: 106 print("Remove %s error! Skipped!"%src) 107 108#Display tips 109def show_burn_tips(): 110 burn_tips_str = ''.join( 111 ["%s\n< ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >\n"%colors['purple'], 112 " BUILD SUCCESS \n", 113 "< ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >\n%s"%colors['end'] 114 ]) 115 print(burn_tips_str) 116 117#Display alert 118def show_alert(msg): 119 print("%s%s%s"%(colors['red'], msg, colors['end'])) 120 121#Simple dd tool. 122def scons_bin_dd(source, target, **kw): 123 seek = kw.get('seek') 124 skip = kw.get('skip') 125 count = kw.get('count') 126 bs = kw.get('bs', 1024) 127 data = None 128 img_data = None 129 if seek is not None: 130 with open(source, 'rb') as src: 131 data = bytearray(src.read()) 132 mode = 'ab+' 133 if os.path.exists(target): 134 mode = 'rb+' 135 with open(target, mode) as image: 136 image.seek(0, 1) 137 img_data = bytearray(image.read()) 138 with open(target, 'wb') as image: 139 if count is not None: 140 append_len = count*bs 141 else: 142 append_len = len(data) 143 old_len = len(img_data) 144 new_len = seek*bs + append_len 145 if new_len > old_len: 146 wr_data = bytearray(new_len) 147 if old_len > 0: 148 wr_data[0:old_len] = img_data 149 img_data = wr_data 150 img_data[seek*bs : new_len] = data[0 : append_len] 151 image.seek(0, 1) 152 image.write(img_data) 153 return True 154 if skip is not None: 155 with open(source, 'rb') as src: 156 src.seek(skip*bs) 157 data = src.read() 158 with open(target, 'wb') as image: 159 image.write(data) 160 return True 161 raise SconsBuildError("%s============== dd PARAMETER INPUT ERROR! =============%s"%(colors['red'], colors['end'])) 162 163def bf_to_str(bf): 164 if bf is None: 165 return '(unknown targets product None in list)' 166 elif bf.node: 167 return '%s: %s'%(str(bf.node), bf.errstr) 168 elif bf.filename: 169 return '%s: %s'%(bf.filename, bf.errstr) 170 else: 171 return str(bf) 172 173""" 174Interfaces for reading the settings made by menuconfig. 175""" 176def scons_usr_string_option(option): 177 options = usr_cfg_main() 178 value = options.get(option) 179 if value: 180 value = value.strip('"') 181 return value 182 183def scons_usr_int_option(option): 184 options = usr_cfg_main() 185 return int(options.get(option)) 186 187def scons_usr_bool_option(option): 188 options = usr_cfg_main() 189 if option in options.keys(): 190 return options[option].lower() 191 return 'n' 192 193""" 194Interfaces for reading the settings of system. 195""" 196def scons_sys_string_option(option): 197 options = sys_cfg_main() 198 if option in options.keys(): 199 return options[option].strip('"') 200 return None 201 202def scons_sys_bool_option(option): 203 options = sys_cfg_main() 204 if option in options.keys(): 205 return options[option].lower() 206 return 'n' 207 208def get_opt_val(options, option): 209 bool_list = ['Y', 'y', 'N', 'n'] 210 if options[option].isdigit(): 211 return int(options.get(option)) 212 elif options[option] in bool_list: 213 return options[option].lower() 214 else: 215 return options[option].strip('"') 216 217def scons_get_cfg_val(option): 218 usr_config = usr_cfg_main() 219 sys_config = sys_cfg_main() 220 if option in usr_config.keys(): 221 return get_opt_val(usr_config, option) 222 elif option in sys_config.keys(): 223 return get_opt_val(sys_config, option) 224 else: 225 return 'n' 226 227def select_added_cfg(macro, macro_val, macro_cfg, depends=None): 228 if isinstance(macro_val, str) and scons_get_cfg_val(macro) == macro_val: 229 if depends is None: 230 temp = deepcopy(macro_cfg) 231 for cfg in macro_cfg: 232 if '$' not in cfg: 233 pass 234 else: 235 tmp_cfg = cfg.split('=')[1].strip('$').strip('(').strip(')').strip() 236 tmp_cfg_val = '%s=%s'%(cfg.split('=')[0], scons_get_cfg_val(tmp_cfg)) 237 temp.append(tmp_cfg_val) 238 temp.remove(cfg) 239 return temp 240 (macro_2, macro_2_val) = depends 241 if scons_get_cfg_val(macro_2) == macro_2_val: 242 return macro_cfg 243 elif not isinstance(macro_val, str): 244 val = scons_get_cfg_val(macro) 245 if 'others' in macro_val: 246 except_list = deepcopy(macro_val) 247 except_list.remove('others') 248 if val in except_list: 249 return macro_cfg[val] 250 else: 251 return macro_cfg['others'] 252 elif val in macro_val: 253 return macro_cfg[val] 254 255 return None 256 257def translate_env_value_to_str(name, macro_cfg, mod_flag): 258 if name == 'defines': 259 if isinstance(macro_cfg, str): 260 return 'DEFINES += -D%s'%macro_cfg if mod_flag is False else 'CCFLAGS += -D%s'%macro_cfg 261 else: 262 defines = ['-D%s'%x for x in macro_cfg if isinstance(x, str)] 263 defines.extend(['-D%s=%s'%x for x in macro_cfg if isinstance(x, tuple)]) 264 return 'DEFINES += %s'%(' '.join(defines)) if mod_flag is False else 'CCFLAGS += %s'%(' '.join(defines)) 265 elif name == 'liteos_inc_path': 266 os_path = '$(MAIN_TOPDIR)/platform/os/Huawei_LiteOS' 267 if isinstance(macro_cfg, str): 268 return 'INCLUDE += -I%s/%s'%(os_path, macro_cfg) if mod_flag is False else 'CCFLAGS += -I%s/%s'%(os_path, macro_cfg) 269 else: 270 includes = ['-I%s/%s'%(os_path, x) for x in macro_cfg] 271 return 'INCLUDE += %s'%('\\\n\t'.join(includes)) if mod_flag is False else 'CCFLAGS += %s'%('\\\n\t'.join(includes)) 272 elif name == 'common_inc_path': 273 if isinstance(macro_cfg, str): 274 inc_str = '-I%s'%(macro_cfg[2:] if macro_cfg.startswith('#') else macro_cfg) 275 return 'INCLUDE += %s'%inc_str if mod_flag is False else 'CCFLAGS += %s'%inc_str 276 else: 277 inc_str = '-I$(MAIN_TOPDIR)/%s'%('\\\n\t-I$(MAIN_TOPDIR)/'.join([x[2:] for x in macro_cfg])) 278 return 'INCLUDE += %s'%inc_str if mod_flag is False else 'CCFLAGS += %s'%inc_str 279 else: 280 if isinstance(macro_cfg, str): 281 return '%s += %s'%(flag_r[name], macro_cfg) 282 else: 283 return '%s += %s'%(flag_r[name], ' '.join(macro_cfg)) 284 285def condition_str(macro, macro_val, macro_cfg, env_type, depends = None, mod_flag = False): 286 if isinstance(macro_val, str): 287 if depends is None: 288 return 'ifeq ($(%s), %s)\n\t%s\nendif\n'%(macro, macro_val, translate_env_value_to_str(env_type, macro_cfg, mod_flag)) 289 else: 290 (macro_2, macro_2_val) = depends 291 return 'ifeq ($(%s)_$(%s), %s_%s)\n\t%s\nendif\n'%(macro, macro_2, macro_val, macro_2_val, translate_env_value_to_str(env_type, macro_cfg, mod_flag)) 292 else: 293 strs = '' 294 val_list = deepcopy(macro_val) 295 val_list.remove('others') if 'others' in val_list else None 296 strs = '%sifeq ($(%s), %s)\n\t%s\n'%(strs, macro, val_list[0], translate_env_value_to_str(env_type, macro_cfg[val_list[0]], mod_flag)) 297 for val in val_list[1:]: 298 strs = '%selse ifeq ($(%s), %s)\n\t%s\n'%(strs, macro, val, translate_env_value_to_str(env_type, macro_cfg[val], mod_flag)) 299 strs = '%selse\n\t%s\n'%(strs, translate_env_value_to_str(env_type, macro_cfg['others'], mod_flag)) if 'others' in macro_val else None 300 strs = '%sendif\n'%strs 301 return strs 302