11bd4fe43Sopenharmony_ci#!/usr/bin/env python3
21bd4fe43Sopenharmony_ci# coding=utf-8
31bd4fe43Sopenharmony_ci
41bd4fe43Sopenharmony_ci'''
51bd4fe43Sopenharmony_ci* Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
61bd4fe43Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License");
71bd4fe43Sopenharmony_ci* you may not use this file except in compliance with the License.
81bd4fe43Sopenharmony_ci* You may obtain a copy of the License at
91bd4fe43Sopenharmony_ci*
101bd4fe43Sopenharmony_ci*     http://www.apache.org/licenses/LICENSE-2.0
111bd4fe43Sopenharmony_ci*
121bd4fe43Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software
131bd4fe43Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS,
141bd4fe43Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151bd4fe43Sopenharmony_ci* See the License for the specific language governing permissions and
161bd4fe43Sopenharmony_ci* limitations under the License.
171bd4fe43Sopenharmony_ci*
181bd4fe43Sopenharmony_ci* Description: Utilities.
191bd4fe43Sopenharmony_ci'''
201bd4fe43Sopenharmony_ci
211bd4fe43Sopenharmony_ciimport os
221bd4fe43Sopenharmony_ciimport shutil
231bd4fe43Sopenharmony_cifrom copy import deepcopy
241bd4fe43Sopenharmony_ci
251bd4fe43Sopenharmony_cifrom hi_config_parser import usr_cfg_main
261bd4fe43Sopenharmony_cifrom hi_config_parser import sys_cfg_main
271bd4fe43Sopenharmony_ci
281bd4fe43Sopenharmony_ciclass SconsBuildError(Exception):
291bd4fe43Sopenharmony_ci    """
301bd4fe43Sopenharmony_ci    Error exception.
311bd4fe43Sopenharmony_ci    """
321bd4fe43Sopenharmony_ci    pass
331bd4fe43Sopenharmony_ci
341bd4fe43Sopenharmony_ci"""
351bd4fe43Sopenharmony_ciColors to display the messages.
361bd4fe43Sopenharmony_ci"""
371bd4fe43Sopenharmony_cicolors = {}
381bd4fe43Sopenharmony_cicolors['cyan']   = '\033[96m'
391bd4fe43Sopenharmony_cicolors['purple'] = '\033[95m'
401bd4fe43Sopenharmony_cicolors['blue']   = '\033[94m'
411bd4fe43Sopenharmony_cicolors['green']  = '\033[92m'
421bd4fe43Sopenharmony_cicolors['yellow'] = '\033[93m'
431bd4fe43Sopenharmony_cicolors['red']    = '\033[91m'
441bd4fe43Sopenharmony_cicolors['end']    = '\033[0m'
451bd4fe43Sopenharmony_ci
461bd4fe43Sopenharmony_ciflag = {
471bd4fe43Sopenharmony_ci    'ARFLAGS' : 'ar_flags',
481bd4fe43Sopenharmony_ci    'CCFLAGS' : 'opts', #'cc_flags',
491bd4fe43Sopenharmony_ci    'ASLAGS' : 'as_flags',
501bd4fe43Sopenharmony_ci    'CPPDEFINES' : 'defines',
511bd4fe43Sopenharmony_ci    'CPPPATH' : ['liteos_inc_path', 'common_inc_path'],
521bd4fe43Sopenharmony_ci    'LINKFLAGS' : 'link_flags',
531bd4fe43Sopenharmony_ci    'LINK_SCRIPTS_FLAG' : 'link_scripts_flag'
541bd4fe43Sopenharmony_ci}
551bd4fe43Sopenharmony_ci
561bd4fe43Sopenharmony_ciflag_r = {
571bd4fe43Sopenharmony_ci    'ar_flags' : 'ARFLAGS',
581bd4fe43Sopenharmony_ci    'opts' : 'CCFLAGS',
591bd4fe43Sopenharmony_ci    'as_flags' : 'ASLAGS',
601bd4fe43Sopenharmony_ci    'defines' : 'CPPDEFINES',
611bd4fe43Sopenharmony_ci    'liteos_inc_path' : 'CPPPATH',
621bd4fe43Sopenharmony_ci    'common_inc_path' : 'CPPPATH',
631bd4fe43Sopenharmony_ci    'link_flags' : 'LINKFLAGS',
641bd4fe43Sopenharmony_ci    'link_scripts_flag' : 'LINK_SCRIPTS_FLAG'
651bd4fe43Sopenharmony_ci}
661bd4fe43Sopenharmony_ci
671bd4fe43Sopenharmony_cidef traverse_subdir(search_dir = '.', full_path = False):
681bd4fe43Sopenharmony_ci    src_path = []
691bd4fe43Sopenharmony_ci    for root, dirs, files in os.walk(search_dir):
701bd4fe43Sopenharmony_ci        if files != []:
711bd4fe43Sopenharmony_ci            src_path.append(os.path.relpath(root, search_dir)) if full_path == False else src_path.append(root)
721bd4fe43Sopenharmony_ci            print('relative dir:',os.path.relpath(root, search_dir) if full_path == False else root)
731bd4fe43Sopenharmony_ci    return src_path
741bd4fe43Sopenharmony_ci
751bd4fe43Sopenharmony_ci#compiler check
761bd4fe43Sopenharmony_cidef scons_env_param_check():
771bd4fe43Sopenharmony_ci    env_path_param = os.environ['PATH'].split(':')
781bd4fe43Sopenharmony_ci    for param in env_path_param:
791bd4fe43Sopenharmony_ci        compiler = os.path.join(param, 'riscv32-unknown-elf-gcc')
801bd4fe43Sopenharmony_ci        if os.path.isfile(compiler):
811bd4fe43Sopenharmony_ci            return True
821bd4fe43Sopenharmony_ci    return False
831bd4fe43Sopenharmony_ci
841bd4fe43Sopenharmony_ci#settings check
851bd4fe43Sopenharmony_cidef scons_pre_check(dir_list):
861bd4fe43Sopenharmony_ci    if len(dir_list) > 0 :
871bd4fe43Sopenharmony_ci        for dir in dir_list:
881bd4fe43Sopenharmony_ci            os.makedir(dir)
891bd4fe43Sopenharmony_ci    usr_config_path = os.path.join('build', 'config', 'usr_config.mk')
901bd4fe43Sopenharmony_ci    if os.path.isfile(usr_config_path) == False:
911bd4fe43Sopenharmony_ci        shutil.copyfile(os.path.join('tools', 'menuconfig', 'default.config'), usr_config_path)
921bd4fe43Sopenharmony_ci    return scons_env_param_check()
931bd4fe43Sopenharmony_ci
941bd4fe43Sopenharmony_ci#delete files while compiling.
951bd4fe43Sopenharmony_cidef cleanup(target, source, env):
961bd4fe43Sopenharmony_ci    for src in source:
971bd4fe43Sopenharmony_ci        name = str(src)
981bd4fe43Sopenharmony_ci        try:
991bd4fe43Sopenharmony_ci            if os.path.isfile(name):
1001bd4fe43Sopenharmony_ci                os.remove(name)
1011bd4fe43Sopenharmony_ci            elif os.path.isdir(name):
1021bd4fe43Sopenharmony_ci                shutil.rmtree(name)
1031bd4fe43Sopenharmony_ci            else:
1041bd4fe43Sopenharmony_ci                print("%s not found! Skipped!"%src)
1051bd4fe43Sopenharmony_ci        except:
1061bd4fe43Sopenharmony_ci            print("Remove %s error! Skipped!"%src)
1071bd4fe43Sopenharmony_ci
1081bd4fe43Sopenharmony_ci#Display tips
1091bd4fe43Sopenharmony_cidef show_burn_tips():
1101bd4fe43Sopenharmony_ci    burn_tips_str = ''.join(
1111bd4fe43Sopenharmony_ci                ["%s\n< ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >\n"%colors['purple'],
1121bd4fe43Sopenharmony_ci                 "                              BUILD SUCCESS                              \n",
1131bd4fe43Sopenharmony_ci                 "< ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >\n%s"%colors['end']
1141bd4fe43Sopenharmony_ci                ])
1151bd4fe43Sopenharmony_ci    print(burn_tips_str)
1161bd4fe43Sopenharmony_ci
1171bd4fe43Sopenharmony_ci#Display alert
1181bd4fe43Sopenharmony_cidef show_alert(msg):
1191bd4fe43Sopenharmony_ci    print("%s%s%s"%(colors['red'], msg, colors['end']))
1201bd4fe43Sopenharmony_ci
1211bd4fe43Sopenharmony_ci#Simple dd tool.
1221bd4fe43Sopenharmony_cidef scons_bin_dd(source, target, **kw):
1231bd4fe43Sopenharmony_ci    seek = kw.get('seek')
1241bd4fe43Sopenharmony_ci    skip = kw.get('skip')
1251bd4fe43Sopenharmony_ci    count = kw.get('count')
1261bd4fe43Sopenharmony_ci    bs = kw.get('bs', 1024)
1271bd4fe43Sopenharmony_ci    data = None
1281bd4fe43Sopenharmony_ci    img_data = None
1291bd4fe43Sopenharmony_ci    if seek is not None:
1301bd4fe43Sopenharmony_ci        with open(source, 'rb') as src:
1311bd4fe43Sopenharmony_ci            data = bytearray(src.read())
1321bd4fe43Sopenharmony_ci        mode = 'ab+'
1331bd4fe43Sopenharmony_ci        if os.path.exists(target):
1341bd4fe43Sopenharmony_ci            mode = 'rb+'
1351bd4fe43Sopenharmony_ci        with open(target, mode) as image:
1361bd4fe43Sopenharmony_ci            image.seek(0, 1)
1371bd4fe43Sopenharmony_ci            img_data = bytearray(image.read())
1381bd4fe43Sopenharmony_ci        with open(target, 'wb') as image:
1391bd4fe43Sopenharmony_ci            if count is not None:
1401bd4fe43Sopenharmony_ci                append_len = count*bs
1411bd4fe43Sopenharmony_ci            else:
1421bd4fe43Sopenharmony_ci                append_len = len(data)
1431bd4fe43Sopenharmony_ci            old_len = len(img_data)
1441bd4fe43Sopenharmony_ci            new_len = seek*bs + append_len
1451bd4fe43Sopenharmony_ci            if new_len > old_len:
1461bd4fe43Sopenharmony_ci                wr_data = bytearray(new_len)
1471bd4fe43Sopenharmony_ci                if old_len > 0:
1481bd4fe43Sopenharmony_ci                    wr_data[0:old_len] = img_data
1491bd4fe43Sopenharmony_ci                img_data = wr_data
1501bd4fe43Sopenharmony_ci            img_data[seek*bs : new_len] = data[0 : append_len]
1511bd4fe43Sopenharmony_ci            image.seek(0, 1)
1521bd4fe43Sopenharmony_ci            image.write(img_data)
1531bd4fe43Sopenharmony_ci        return True
1541bd4fe43Sopenharmony_ci    if skip is not None:
1551bd4fe43Sopenharmony_ci        with open(source, 'rb') as src:
1561bd4fe43Sopenharmony_ci            src.seek(skip*bs)
1571bd4fe43Sopenharmony_ci            data = src.read()
1581bd4fe43Sopenharmony_ci        with open(target, 'wb') as image:
1591bd4fe43Sopenharmony_ci            image.write(data)
1601bd4fe43Sopenharmony_ci        return True
1611bd4fe43Sopenharmony_ci    raise SconsBuildError("%s============== dd PARAMETER INPUT ERROR! =============%s"%(colors['red'], colors['end']))
1621bd4fe43Sopenharmony_ci
1631bd4fe43Sopenharmony_cidef bf_to_str(bf):
1641bd4fe43Sopenharmony_ci    if bf is None:
1651bd4fe43Sopenharmony_ci        return '(unknown targets product None in list)'
1661bd4fe43Sopenharmony_ci    elif bf.node:
1671bd4fe43Sopenharmony_ci        return '%s: %s'%(str(bf.node), bf.errstr)
1681bd4fe43Sopenharmony_ci    elif bf.filename:
1691bd4fe43Sopenharmony_ci        return '%s: %s'%(bf.filename, bf.errstr)
1701bd4fe43Sopenharmony_ci    else:
1711bd4fe43Sopenharmony_ci        return str(bf)
1721bd4fe43Sopenharmony_ci
1731bd4fe43Sopenharmony_ci"""
1741bd4fe43Sopenharmony_ciInterfaces for reading the settings made by menuconfig.
1751bd4fe43Sopenharmony_ci"""
1761bd4fe43Sopenharmony_cidef scons_usr_string_option(option):
1771bd4fe43Sopenharmony_ci    options = usr_cfg_main()
1781bd4fe43Sopenharmony_ci    value = options.get(option)
1791bd4fe43Sopenharmony_ci    if value:
1801bd4fe43Sopenharmony_ci        value = value.strip('"')
1811bd4fe43Sopenharmony_ci    return value
1821bd4fe43Sopenharmony_ci
1831bd4fe43Sopenharmony_cidef scons_usr_int_option(option):
1841bd4fe43Sopenharmony_ci    options = usr_cfg_main()
1851bd4fe43Sopenharmony_ci    return int(options.get(option))
1861bd4fe43Sopenharmony_ci
1871bd4fe43Sopenharmony_cidef scons_usr_bool_option(option):
1881bd4fe43Sopenharmony_ci    options = usr_cfg_main()
1891bd4fe43Sopenharmony_ci    if option in options.keys():
1901bd4fe43Sopenharmony_ci        return options[option].lower()
1911bd4fe43Sopenharmony_ci    return 'n'
1921bd4fe43Sopenharmony_ci
1931bd4fe43Sopenharmony_ci"""
1941bd4fe43Sopenharmony_ciInterfaces for reading the settings of system.
1951bd4fe43Sopenharmony_ci"""
1961bd4fe43Sopenharmony_cidef scons_sys_string_option(option):
1971bd4fe43Sopenharmony_ci    options = sys_cfg_main()
1981bd4fe43Sopenharmony_ci    if option in options.keys():
1991bd4fe43Sopenharmony_ci        return options[option].strip('"')
2001bd4fe43Sopenharmony_ci    return None
2011bd4fe43Sopenharmony_ci
2021bd4fe43Sopenharmony_cidef scons_sys_bool_option(option):
2031bd4fe43Sopenharmony_ci    options = sys_cfg_main()
2041bd4fe43Sopenharmony_ci    if option in options.keys():
2051bd4fe43Sopenharmony_ci        return options[option].lower()
2061bd4fe43Sopenharmony_ci    return 'n'
2071bd4fe43Sopenharmony_ci
2081bd4fe43Sopenharmony_cidef get_opt_val(options, option):
2091bd4fe43Sopenharmony_ci    bool_list = ['Y', 'y', 'N', 'n']
2101bd4fe43Sopenharmony_ci    if options[option].isdigit():
2111bd4fe43Sopenharmony_ci        return int(options.get(option))
2121bd4fe43Sopenharmony_ci    elif options[option] in bool_list:
2131bd4fe43Sopenharmony_ci        return options[option].lower()
2141bd4fe43Sopenharmony_ci    else:
2151bd4fe43Sopenharmony_ci        return options[option].strip('"')
2161bd4fe43Sopenharmony_ci
2171bd4fe43Sopenharmony_cidef scons_get_cfg_val(option):
2181bd4fe43Sopenharmony_ci    usr_config = usr_cfg_main()
2191bd4fe43Sopenharmony_ci    sys_config = sys_cfg_main()
2201bd4fe43Sopenharmony_ci    if option in usr_config.keys():
2211bd4fe43Sopenharmony_ci        return get_opt_val(usr_config, option)
2221bd4fe43Sopenharmony_ci    elif option in sys_config.keys():
2231bd4fe43Sopenharmony_ci        return get_opt_val(sys_config, option)
2241bd4fe43Sopenharmony_ci    else:
2251bd4fe43Sopenharmony_ci        return 'n'
2261bd4fe43Sopenharmony_ci
2271bd4fe43Sopenharmony_cidef select_added_cfg(macro, macro_val, macro_cfg, depends=None):
2281bd4fe43Sopenharmony_ci    if isinstance(macro_val, str) and scons_get_cfg_val(macro) == macro_val:
2291bd4fe43Sopenharmony_ci        if depends is None:
2301bd4fe43Sopenharmony_ci            temp = deepcopy(macro_cfg)
2311bd4fe43Sopenharmony_ci            for cfg in macro_cfg:
2321bd4fe43Sopenharmony_ci                if '$' not in cfg:
2331bd4fe43Sopenharmony_ci                    pass
2341bd4fe43Sopenharmony_ci                else:
2351bd4fe43Sopenharmony_ci                    tmp_cfg = cfg.split('=')[1].strip('$').strip('(').strip(')').strip()
2361bd4fe43Sopenharmony_ci                    tmp_cfg_val = '%s=%s'%(cfg.split('=')[0], scons_get_cfg_val(tmp_cfg))
2371bd4fe43Sopenharmony_ci                    temp.append(tmp_cfg_val)
2381bd4fe43Sopenharmony_ci                    temp.remove(cfg)
2391bd4fe43Sopenharmony_ci            return temp
2401bd4fe43Sopenharmony_ci        (macro_2, macro_2_val) = depends
2411bd4fe43Sopenharmony_ci        if scons_get_cfg_val(macro_2) == macro_2_val:
2421bd4fe43Sopenharmony_ci            return macro_cfg
2431bd4fe43Sopenharmony_ci    elif not isinstance(macro_val, str):
2441bd4fe43Sopenharmony_ci        val = scons_get_cfg_val(macro)
2451bd4fe43Sopenharmony_ci        if 'others' in macro_val:
2461bd4fe43Sopenharmony_ci            except_list = deepcopy(macro_val)
2471bd4fe43Sopenharmony_ci            except_list.remove('others')
2481bd4fe43Sopenharmony_ci            if val in except_list:
2491bd4fe43Sopenharmony_ci                return macro_cfg[val]
2501bd4fe43Sopenharmony_ci            else:
2511bd4fe43Sopenharmony_ci                return macro_cfg['others']
2521bd4fe43Sopenharmony_ci        elif val in macro_val:
2531bd4fe43Sopenharmony_ci            return macro_cfg[val]
2541bd4fe43Sopenharmony_ci
2551bd4fe43Sopenharmony_ci    return None
2561bd4fe43Sopenharmony_ci
2571bd4fe43Sopenharmony_cidef translate_env_value_to_str(name, macro_cfg, mod_flag):
2581bd4fe43Sopenharmony_ci    if name == 'defines':
2591bd4fe43Sopenharmony_ci        if isinstance(macro_cfg, str):
2601bd4fe43Sopenharmony_ci            return 'DEFINES += -D%s'%macro_cfg if mod_flag is False else 'CCFLAGS += -D%s'%macro_cfg
2611bd4fe43Sopenharmony_ci        else:
2621bd4fe43Sopenharmony_ci            defines = ['-D%s'%x for x in macro_cfg if isinstance(x, str)]
2631bd4fe43Sopenharmony_ci            defines.extend(['-D%s=%s'%x for x in macro_cfg if isinstance(x, tuple)])
2641bd4fe43Sopenharmony_ci            return 'DEFINES += %s'%(' '.join(defines)) if mod_flag is False else 'CCFLAGS += %s'%(' '.join(defines))
2651bd4fe43Sopenharmony_ci    elif name == 'liteos_inc_path':
2661bd4fe43Sopenharmony_ci        os_path = '$(MAIN_TOPDIR)/platform/os/Huawei_LiteOS'
2671bd4fe43Sopenharmony_ci        if isinstance(macro_cfg, str):
2681bd4fe43Sopenharmony_ci            return 'INCLUDE += -I%s/%s'%(os_path, macro_cfg) if mod_flag is False else 'CCFLAGS += -I%s/%s'%(os_path, macro_cfg)
2691bd4fe43Sopenharmony_ci        else:
2701bd4fe43Sopenharmony_ci            includes = ['-I%s/%s'%(os_path, x) for x in macro_cfg]
2711bd4fe43Sopenharmony_ci            return 'INCLUDE += %s'%('\\\n\t'.join(includes)) if mod_flag is False else 'CCFLAGS += %s'%('\\\n\t'.join(includes))
2721bd4fe43Sopenharmony_ci    elif name == 'common_inc_path':
2731bd4fe43Sopenharmony_ci        if isinstance(macro_cfg, str):
2741bd4fe43Sopenharmony_ci            inc_str = '-I%s'%(macro_cfg[2:] if macro_cfg.startswith('#') else macro_cfg)
2751bd4fe43Sopenharmony_ci            return 'INCLUDE += %s'%inc_str if mod_flag is False else 'CCFLAGS += %s'%inc_str
2761bd4fe43Sopenharmony_ci        else:
2771bd4fe43Sopenharmony_ci            inc_str = '-I$(MAIN_TOPDIR)/%s'%('\\\n\t-I$(MAIN_TOPDIR)/'.join([x[2:] for x in macro_cfg]))
2781bd4fe43Sopenharmony_ci            return 'INCLUDE += %s'%inc_str if mod_flag is False else 'CCFLAGS += %s'%inc_str
2791bd4fe43Sopenharmony_ci    else:
2801bd4fe43Sopenharmony_ci        if isinstance(macro_cfg, str):
2811bd4fe43Sopenharmony_ci            return '%s += %s'%(flag_r[name], macro_cfg)
2821bd4fe43Sopenharmony_ci        else:
2831bd4fe43Sopenharmony_ci            return '%s += %s'%(flag_r[name], ' '.join(macro_cfg))
2841bd4fe43Sopenharmony_ci
2851bd4fe43Sopenharmony_cidef condition_str(macro, macro_val, macro_cfg, env_type, depends = None, mod_flag = False):
2861bd4fe43Sopenharmony_ci    if isinstance(macro_val, str):
2871bd4fe43Sopenharmony_ci        if depends is None:
2881bd4fe43Sopenharmony_ci            return 'ifeq ($(%s), %s)\n\t%s\nendif\n'%(macro, macro_val, translate_env_value_to_str(env_type, macro_cfg, mod_flag))
2891bd4fe43Sopenharmony_ci        else:
2901bd4fe43Sopenharmony_ci            (macro_2, macro_2_val) = depends
2911bd4fe43Sopenharmony_ci            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))
2921bd4fe43Sopenharmony_ci    else:
2931bd4fe43Sopenharmony_ci        strs = ''
2941bd4fe43Sopenharmony_ci        val_list = deepcopy(macro_val)
2951bd4fe43Sopenharmony_ci        val_list.remove('others') if 'others' in val_list else None
2961bd4fe43Sopenharmony_ci        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))
2971bd4fe43Sopenharmony_ci        for val in val_list[1:]:
2981bd4fe43Sopenharmony_ci            strs = '%selse ifeq ($(%s), %s)\n\t%s\n'%(strs, macro, val, translate_env_value_to_str(env_type, macro_cfg[val], mod_flag))
2991bd4fe43Sopenharmony_ci        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
3001bd4fe43Sopenharmony_ci        strs = '%sendif\n'%strs
3011bd4fe43Sopenharmony_ci        return strs
302