## File : building.py# This file is part of RT-Thread RTOS# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License along# with this program; if not, write to the Free Software Foundation, Inc.,# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.## Change Logs:# Date Author Notes# 2015年01月20日 Bernard Add copyright information# 2015年07月25日 Bernard Add LOCAL_CCFLAGS/LOCAL_CPPPATH/LOCAL_CPPDEFINES for# group definition.#import osimport sysimport stringimport utilsfrom SCons.Script import *from utils import _make_path_relativefrom mkdist import do_copy_fileBuildOptions = {}Projects = []Rtt_Root = ''Env = None# SCons PreProcessor patchdef start_handling_includes(self, t=None):"""Causes the PreProcessor object to start processing #import,#include and #include_next lines.This method will be called when a #if, #ifdef, #ifndef or #elifevaluates True, or when we reach the #else in a #if, #ifdef,#ifndef or #elif block where a condition already evaluatedFalse."""d = self.dispatch_tablep = self.stack[-1] if self.stack else self.default_tablefor k in ('import', 'include', 'include_next', 'define'):d[k] = p[k]def stop_handling_includes(self, t=None):"""Causes the PreProcessor object to stop processing #import,#include and #include_next lines.This method will be called when a #if, #ifdef, #ifndef or #elifevaluates False, or when we reach the #else in a #if, #ifdef,#ifndef or #elif block where a condition already evaluated True."""d = self.dispatch_tabled['import'] = self.do_nothingd['include'] = self.do_nothingd['include_next'] = self.do_nothingd['define'] = self.do_nothingPatchedPreProcessor = SCons.cpp.PreProcessorPatchedPreProcessor.start_handling_includes = start_handling_includesPatchedPreProcessor.stop_handling_includes = stop_handling_includesclass Win32Spawn:def spawn(self, sh, escape, cmd, args, env):# deal with the cmd build-in commands which cannot be used in# subprocess.Popenif cmd == 'del':for f in args[1:]:try:os.remove(f)except Exception as e:print ('Error removing file: ' + e)return -1return 0import subprocessnewargs = ' '.join(args[1:])cmdline = cmd + " " + newargs# Make sure the env is constructed by strings_e = dict([(k, str(v)) for k, v in env.items()])# Windows(tm) CreateProcess does not use the env passed to it to find# the executables. So we have to modify our own PATH to make Popen# work.old_path = os.environ['PATH']os.environ['PATH'] = _e['PATH']try:proc = subprocess.Popen(cmdline, env=_e, shell=False)except Exception as e:print ('Error in calling command:' + cmdline.split(' ')[0])print ('Exception: ' + os.strerror(e.errno))if (os.strerror(e.errno) == "No such file or directory"):print ("\nPlease check Toolchains PATH setting.\n")return e.errnofinally:os.environ['PATH'] = old_pathreturn proc.wait()# generate cconfig.h filedef GenCconfigFile(env, BuildOptions):import rtconfigif rtconfig.PLATFORM == 'gcc':contents = ''if not os.path.isfile('cconfig.h'):import gccgcc.GenerateGCCConfig(rtconfig)# try againif os.path.isfile('cconfig.h'):f = open('cconfig.h', 'r')if f:contents = f.read()f.close()prep = PatchedPreProcessor()prep.process_contents(contents)options = prep.cpp_namespaceBuildOptions.update(options)# add HAVE_CCONFIG_H definitionenv.AppendUnique(CPPDEFINES = ['HAVE_CCONFIG_H'])def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = []):import rtconfigglobal BuildOptionsglobal Projectsglobal Envglobal Rtt_Root# ===== Add option to SCons =====AddOption('--dist',dest = 'make-dist',action = 'store_true',default = False,help = 'make distribution')AddOption('--dist-strip',dest = 'make-dist-strip',action = 'store_true',default = False,help = 'make distribution and strip useless files')AddOption('--cscope',dest = 'cscope',action = 'store_true',default = False,help = 'Build Cscope cross reference database. Requires cscope installed.')AddOption('--clang-analyzer',dest = 'clang-analyzer',action = 'store_true',default = False,help = 'Perform static analyze with Clang-analyzer. ' + \'Requires Clang installed.\n' + \'It is recommended to use with scan-build like this:\n' + \'`scan-build scons --clang-analyzer`\n' + \'If things goes well, scan-build will instruct you to invoke scan-view.')AddOption('--buildlib',dest = 'buildlib',type = 'string',help = 'building library of a component')AddOption('--cleanlib',dest = 'cleanlib',action = 'store_true',default = False,help = 'clean up the library by --buildlib')AddOption('--target',dest = 'target',type = 'string',help = 'set target project: mdk/mdk4/mdk5/iar/vs/vsc/ua/cdk/ses')AddOption('--genconfig',dest = 'genconfig',action = 'store_true',default = False,help = 'Generate .config from rtconfig.h')AddOption('--useconfig',dest = 'useconfig',type = 'string',help = 'make rtconfig.h from config file.')AddOption('--verbose',dest = 'verbose',action = 'store_true',default = False,help = 'print verbose information during build')Env = envRtt_Root = os.path.abspath(root_directory)# make an absolute root directoryRTT_ROOT = Rtt_RootExport('RTT_ROOT')# set RTT_ROOT in ENVEnv['RTT_ROOT'] = Rtt_Root# set BSP_ROOT in ENVEnv['BSP_ROOT'] = Dir('#').abspathsys.path = sys.path + [os.path.join(Rtt_Root, 'tools')]# {target_name:(CROSS_TOOL, PLATFORM)}tgt_dict = {'mdk':('keil', 'armcc'),'mdk4':('keil', 'armcc'),'mdk5':('keil', 'armcc'),'iar':('iar', 'iar'),'vs':('msvc', 'cl'),'vs2012':('msvc', 'cl'),'vsc' : ('gcc', 'gcc'),'cb':('keil', 'armcc'),'ua':('gcc', 'gcc'),'cdk':('gcc', 'gcc'),'ses' : ('gcc', 'gcc')}tgt_name = GetOption('target')if tgt_name:# --target will change the toolchain settings which clang-analyzer is# depend onif GetOption('clang-analyzer'):print ('--clang-analyzer cannot be used with --target')sys.exit(1)SetOption('no_exec', 1)try:rtconfig.CROSS_TOOL, rtconfig.PLATFORM = tgt_dict[tgt_name]# replace the 'RTT_CC' to 'CROSS_TOOL'os.environ['RTT_CC'] = rtconfig.CROSS_TOOLutils.ReloadModule(rtconfig)except KeyError:print ('Unknow target: '+ tgt_name+'. Avaible targets: ' +', '.join(tgt_dict.keys()))sys.exit(1)elif (GetDepend('RT_USING_NEWLIB') == False and GetDepend('RT_USING_NOLIBC') == False) \and rtconfig.PLATFORM == 'gcc':AddDepend('RT_USING_MINILIBC')# auto change the 'RTT_EXEC_PATH' when 'rtconfig.EXEC_PATH' get failedif not os.path.exists(rtconfig.EXEC_PATH):if 'RTT_EXEC_PATH' in os.environ:# del the 'RTT_EXEC_PATH' and using the 'EXEC_PATH' setting on rtconfig.pydel os.environ['RTT_EXEC_PATH']utils.ReloadModule(rtconfig)# add compability with Keil MDK 4.6 which changes the directory of armcc.exeif rtconfig.PLATFORM == 'armcc':if not os.path.isfile(os.path.join(rtconfig.EXEC_PATH, 'armcc.exe')):if rtconfig.EXEC_PATH.find('bin40') > 0:rtconfig.EXEC_PATH = rtconfig.EXEC_PATH.replace('bin40', 'armcc/bin')Env['LINKFLAGS'] = Env['LINKFLAGS'].replace('RV31', 'armcc')# reset AR command flagsenv['ARCOM'] = '$AR --create $TARGET $SOURCES'env['LIBPREFIX'] = ''env['LIBSUFFIX'] = '.lib'env['LIBLINKPREFIX'] = ''env['LIBLINKSUFFIX'] = '.lib'env['LIBDIRPREFIX'] = '--userlibpath 'elif rtconfig.PLATFORM == 'iar':env['LIBPREFIX'] = ''env['LIBSUFFIX'] = '.a'env['LIBLINKPREFIX'] = ''env['LIBLINKSUFFIX'] = '.a'env['LIBDIRPREFIX'] = '--search '# patch for win32 spawnif env['PLATFORM'] == 'win32':win32_spawn = Win32Spawn()win32_spawn.env = envenv['SPAWN'] = win32_spawn.spawnif env['PLATFORM'] == 'win32':os.environ['PATH'] = rtconfig.EXEC_PATH + ";" + os.environ['PATH']else:os.environ['PATH'] = rtconfig.EXEC_PATH + ":" + os.environ['PATH']# add program pathenv.PrependENVPath('PATH', rtconfig.EXEC_PATH)# add rtconfig.h/BSP path into Kernel groupDefineGroup("Kernel", [], [], CPPPATH=[str(Dir('#').abspath)])# add library build actionact = SCons.Action.Action(BuildLibInstallAction, 'Install compiled library... $TARGET')bld = Builder(action = act)Env.Append(BUILDERS = {'BuildLib': bld})# parse rtconfig.h to get used componentPreProcessor = PatchedPreProcessor()f = open('rtconfig.h', 'r')contents = f.read()f.close()PreProcessor.process_contents(contents)BuildOptions = PreProcessor.cpp_namespaceif GetOption('clang-analyzer'):# perform what scan-build doesenv.Replace(CC = 'ccc-analyzer',CXX = 'c++-analyzer',# skip as and linkLINK = 'true',AS = 'true',)env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_"))# only check, don't compile. ccc-analyzer use CCC_CC as the CC.# fsyntax-only will give us some additional warning messagesenv['ENV']['CCC_CC'] = 'clang'env.Append(CFLAGS=['-fsyntax-only', '-Wall', '-Wno-invalid-source-encoding'])env['ENV']['CCC_CXX'] = 'clang++'env.Append(CXXFLAGS=['-fsyntax-only', '-Wall', '-Wno-invalid-source-encoding'])# remove the POST_ACTION as it will cause meaningless errors(file not# found or something like that).rtconfig.POST_ACTION = ''# generate cconfig.h fileGenCconfigFile(env, BuildOptions)# auto append '_REENT_SMALL' when using newlib 'nano.specs' optionif rtconfig.PLATFORM == 'gcc' and str(env['LINKFLAGS']).find('nano.specs') != -1:env.AppendUnique(CPPDEFINES = ['_REENT_SMALL'])if GetOption('genconfig'):from genconf import genconfiggenconfig()exit(0)if env['PLATFORM'] != 'win32':AddOption('--menuconfig',dest = 'menuconfig',action = 'store_true',default = False,help = 'make menuconfig for RT-Thread BSP')if GetOption('menuconfig'):from menuconfig import menuconfigmenuconfig(Rtt_Root)exit(0)AddOption('--pyconfig',dest = 'pyconfig',action = 'store_true',default = False,help = 'make menuconfig for RT-Thread BSP')AddOption('--pyconfig-silent',dest = 'pyconfig_silent',action = 'store_true',default = False,help = 'Don`t show pyconfig window')if GetOption('pyconfig_silent'):from menuconfig import pyconfig_silentpyconfig_silent(Rtt_Root)exit(0)elif GetOption('pyconfig'):from menuconfig import pyconfigpyconfig(Rtt_Root)exit(0)configfn = GetOption('useconfig')if configfn:from menuconfig import mk_rtconfigmk_rtconfig(configfn)exit(0)if not GetOption('verbose'):# override the default verbose command stringenv.Replace(ARCOMSTR = 'AR $TARGET',ASCOMSTR = 'AS $TARGET',ASPPCOMSTR = 'AS $TARGET',CCCOMSTR = 'CC $TARGET',CXXCOMSTR = 'CXX $TARGET',LINKCOMSTR = 'LINK $TARGET')# fix the linker for C++if GetDepend('RT_USING_CPLUSPLUS'):if env['LINK'].find('gcc') != -1:env['LINK'] = env['LINK'].replace('gcc', 'g++')# we need to seperate the variant_dir for BSPs and the kernels. BSPs could# have their own components etc. If they point to the same folder, SCons# would find the wrong source code to compile.bsp_vdir = 'build'kernel_vdir = 'build/kernel'# board build scriptobjs = SConscript('SConscript', variant_dir=bsp_vdir, duplicate=0)# include kernelobjs.extend(SConscript(Rtt_Root + '/src/SConscript', variant_dir=kernel_vdir + '/src', duplicate=0))# include libcpuif not has_libcpu:objs.extend(SConscript(Rtt_Root + '/libcpu/SConscript',variant_dir=kernel_vdir + '/libcpu', duplicate=0))# include componentsobjs.extend(SConscript(Rtt_Root + '/components/SConscript',variant_dir=kernel_vdir + '/components',duplicate=0,exports='remove_components'))return objsdef PrepareModuleBuilding(env, root_directory, bsp_directory):import rtconfigglobal BuildOptionsglobal Envglobal Rtt_Root# patch for win32 spawnif env['PLATFORM'] == 'win32':win32_spawn = Win32Spawn()win32_spawn.env = envenv['SPAWN'] = win32_spawn.spawnEnv = envRtt_Root = root_directory# parse bsp rtconfig.h to get used componentPreProcessor = PatchedPreProcessor()f = open(bsp_directory + '/rtconfig.h', 'r')contents = f.read()f.close()PreProcessor.process_contents(contents)BuildOptions = PreProcessor.cpp_namespace# add build/clean library option for library checkingAddOption('--buildlib',dest='buildlib',type='string',help='building library of a component')AddOption('--cleanlib',dest='cleanlib',action='store_true',default=False,help='clean up the library by --buildlib')# add program pathenv.PrependENVPath('PATH', rtconfig.EXEC_PATH)def GetConfigValue(name):assert type(name) == str, 'GetConfigValue: only string parameter is valid'try:return BuildOptions[name]except:return ''def GetDepend(depend):building = Trueif type(depend) == type('str'):if not depend in BuildOptions or BuildOptions[depend] == 0:building = Falseelif BuildOptions[depend] != '':return BuildOptions[depend]return building# for list type dependfor item in depend:if item != '':if not item in BuildOptions or BuildOptions[item] == 0:building = Falsereturn buildingdef LocalOptions(config_filename):from SCons.Script import SCons# parse wiced_config.h to get used componentPreProcessor = SCons.cpp.PreProcessor()f = open(config_filename, 'r')contents = f.read()f.close()PreProcessor.process_contents(contents)local_options = PreProcessor.cpp_namespacereturn local_optionsdef GetLocalDepend(options, depend):building = Trueif type(depend) == type('str'):if not depend in options or options[depend] == 0:building = Falseelif options[depend] != '':return options[depend]return building# for list type dependfor item in depend:if item != '':if not item in options or options[item] == 0:building = Falsereturn buildingdef AddDepend(option):BuildOptions[option] = 1def MergeGroup(src_group, group):src_group['src'] = src_group['src'] + group['src']if 'CCFLAGS' in group:if 'CCFLAGS' in src_group:src_group['CCFLAGS'] = src_group['CCFLAGS'] + group['CCFLAGS']else:src_group['CCFLAGS'] = group['CCFLAGS']if 'CPPPATH' in group:if 'CPPPATH' in src_group:src_group['CPPPATH'] = src_group['CPPPATH'] + group['CPPPATH']else:src_group['CPPPATH'] = group['CPPPATH']if 'CPPDEFINES' in group:if 'CPPDEFINES' in src_group:src_group['CPPDEFINES'] = src_group['CPPDEFINES'] + group['CPPDEFINES']else:src_group['CPPDEFINES'] = group['CPPDEFINES']if 'ASFLAGS' in group:if 'ASFLAGS' in src_group:src_group['ASFLAGS'] = src_group['ASFLAGS'] + group['ASFLAGS']else:src_group['ASFLAGS'] = group['ASFLAGS']# for local CCFLAGS/CPPPATH/CPPDEFINESif 'LOCAL_CCFLAGS' in group:if 'LOCAL_CCFLAGS' in src_group:src_group['LOCAL_CCFLAGS'] = src_group['LOCAL_CCFLAGS'] + group['LOCAL_CCFLAGS']else:src_group['LOCAL_CCFLAGS'] = group['LOCAL_CCFLAGS']if 'LOCAL_CPPPATH' in group:if 'LOCAL_CPPPATH' in src_group:src_group['LOCAL_CPPPATH'] = src_group['LOCAL_CPPPATH'] + group['LOCAL_CPPPATH']else:src_group['LOCAL_CPPPATH'] = group['LOCAL_CPPPATH']if 'LOCAL_CPPDEFINES' in group:if 'LOCAL_CPPDEFINES' in src_group:src_group['LOCAL_CPPDEFINES'] = src_group['LOCAL_CPPDEFINES'] + group['LOCAL_CPPDEFINES']else:src_group['LOCAL_CPPDEFINES'] = group['LOCAL_CPPDEFINES']if 'LINKFLAGS' in group:if 'LINKFLAGS' in src_group:src_group['LINKFLAGS'] = src_group['LINKFLAGS'] + group['LINKFLAGS']else:src_group['LINKFLAGS'] = group['LINKFLAGS']if 'LIBS' in group:if 'LIBS' in src_group:src_group['LIBS'] = src_group['LIBS'] + group['LIBS']else:src_group['LIBS'] = group['LIBS']if 'LIBPATH' in group:if 'LIBPATH' in src_group:src_group['LIBPATH'] = src_group['LIBPATH'] + group['LIBPATH']else:src_group['LIBPATH'] = group['LIBPATH']if 'LOCAL_ASFLAGS' in group:if 'LOCAL_ASFLAGS' in src_group:src_group['LOCAL_ASFLAGS'] = src_group['LOCAL_ASFLAGS'] + group['LOCAL_ASFLAGS']else:src_group['LOCAL_ASFLAGS'] = group['LOCAL_ASFLAGS']def DefineGroup(name, src, depend, **parameters):global Envif not GetDepend(depend):return []# find exist group and get path of groupgroup_path = ''for g in Projects:if g['name'] == name:group_path = g['path']if group_path == '':group_path = GetCurrentDir()group = parametersgroup['name'] = namegroup['path'] = group_pathif type(src) == type([]):group['src'] = File(src)else:group['src'] = srcif 'CCFLAGS' in group:Env.AppendUnique(CCFLAGS = group['CCFLAGS'])if 'CPPPATH' in group:paths = []for item in group['CPPPATH']:paths.append(os.path.abspath(item))group['CPPPATH'] = pathsEnv.AppendUnique(CPPPATH = group['CPPPATH'])if 'CPPDEFINES' in group:Env.AppendUnique(CPPDEFINES = group['CPPDEFINES'])if 'LINKFLAGS' in group:Env.AppendUnique(LINKFLAGS = group['LINKFLAGS'])if 'ASFLAGS' in group:Env.AppendUnique(ASFLAGS = group['ASFLAGS'])if 'LOCAL_CPPPATH' in group:paths = []for item in group['LOCAL_CPPPATH']:paths.append(os.path.abspath(item))group['LOCAL_CPPPATH'] = pathsimport rtconfigif rtconfig.PLATFORM == 'gcc':if 'CCFLAGS' in group:group['CCFLAGS'] = utils.GCCC99Patch(group['CCFLAGS'])if 'LOCAL_CCFLAGS' in group:group['LOCAL_CCFLAGS'] = utils.GCCC99Patch(group['LOCAL_CCFLAGS'])# check whether to clean up libraryif GetOption('cleanlib') and os.path.exists(os.path.join(group['path'], GroupLibFullName(name, Env))):if group['src'] != []:print ('Remove library:'+ GroupLibFullName(name, Env))fn = os.path.join(group['path'], GroupLibFullName(name, Env))if os.path.exists(fn):os.unlink(fn)if 'LIBS' in group:Env.AppendUnique(LIBS = group['LIBS'])if 'LIBPATH' in group:Env.AppendUnique(LIBPATH = group['LIBPATH'])# check whether to build group libraryif 'LIBRARY' in group:objs = Env.Library(name, group['src'])else:# only add sourceobjs = group['src']# merge groupfor g in Projects:if g['name'] == name:# merge to this groupMergeGroup(g, group)return objs# add a new groupProjects.append(group)return objsdef GetCurrentDir():conscript = File('SConscript')fn = conscript.rfile()name = fn.namepath = os.path.dirname(fn.abspath)return pathPREBUILDING = []def RegisterPreBuildingAction(act):global PREBUILDINGassert callable(act), 'Could only register callable objects. %s received' % repr(act)PREBUILDING.append(act)def PreBuilding():global PREBUILDINGfor a in PREBUILDING:a()def GroupLibName(name, env):import rtconfigif rtconfig.PLATFORM == 'armcc':return name + '_rvds'elif rtconfig.PLATFORM == 'gcc':return name + '_gcc'return namedef GroupLibFullName(name, env):return env['LIBPREFIX'] + GroupLibName(name, env) + env['LIBSUFFIX']def BuildLibInstallAction(target, source, env):lib_name = GetOption('buildlib')for Group in Projects:if Group['name'] == lib_name:lib_name = GroupLibFullName(Group['name'], env)dst_name = os.path.join(Group['path'], lib_name)print ('Copy '+lib_name+' => ' +dst_name)do_copy_file(lib_name, dst_name)breakdef DoBuilding(target, objects):# merge all objects into one listdef one_list(l):lst = []for item in l:if type(item) == type([]):lst += one_list(item)else:lst.append(item)return lst# handle local groupdef local_group(group, objects):if 'LOCAL_CCFLAGS' in group or 'LOCAL_CPPPATH' in group or 'LOCAL_CPPDEFINES' in group or 'LOCAL_ASFLAGS' in group:CCFLAGS = Env.get('CCFLAGS', '') + group.get('LOCAL_CCFLAGS', '')CPPPATH = Env.get('CPPPATH', ['']) + group.get('LOCAL_CPPPATH', [''])CPPDEFINES = Env.get('CPPDEFINES', ['']) + group.get('LOCAL_CPPDEFINES', [''])ASFLAGS = Env.get('ASFLAGS', '') + group.get('LOCAL_ASFLAGS', '')for source in group['src']:objects.append(Env.Object(source, CCFLAGS = CCFLAGS, ASFLAGS = ASFLAGS,CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES))return Truereturn Falseobjects = one_list(objects)program = None# check whether special buildlib optionlib_name = GetOption('buildlib')if lib_name:objects = [] # remove all of objects# build library with special componentfor Group in Projects:if Group['name'] == lib_name:lib_name = GroupLibName(Group['name'], Env)if not local_group(Group, objects):objects = Env.Object(Group['src'])program = Env.Library(lib_name, objects)# add library copy actionEnv.BuildLib(lib_name, program)breakelse:# remove source files with local flags settingfor group in Projects:if 'LOCAL_CCFLAGS' in group or 'LOCAL_CPPPATH' in group or 'LOCAL_CPPDEFINES' in group:for source in group['src']:for obj in objects:if source.abspath == obj.abspath or (len(obj.sources) > 0 and source.abspath == obj.sources[0].abspath):objects.remove(obj)# re-add the source files to the objectsfor group in Projects:local_group(group, objects)program = Env.Program(target, objects)EndBuilding(target, program)def GenTargetProject(program = None):if GetOption('target') == 'mdk':from keil import MDKProjectfrom keil import MDK4Projectfrom keil import MDK5Projecttemplate = os.path.isfile('template.Uv2')if template:MDKProject('project.Uv2', Projects)else:template = os.path.isfile('template.uvproj')if template:MDK4Project('project.uvproj', Projects)else:template = os.path.isfile('template.uvprojx')if template:MDK5Project('project.uvprojx', Projects)else:print ('No template project file found.')if GetOption('target') == 'mdk4':from keil import MDK4ProjectMDK4Project('project.uvproj', Projects)if GetOption('target') == 'mdk5':from keil import MDK5ProjectMDK5Project('project.uvprojx', Projects)if GetOption('target') == 'iar':from iar import IARProjectIARProject('project.ewp', Projects)if GetOption('target') == 'vs':from vs import VSProjectVSProject('project.vcproj', Projects, program)if GetOption('target') == 'vs2012':from vs2012 import VS2012ProjectVS2012Project('project.vcxproj', Projects, program)if GetOption('target') == 'cb':from codeblocks import CBProjectCBProject('project.cbp', Projects, program)if GetOption('target') == 'ua':from ua import PrepareUAPrepareUA(Projects, Rtt_Root, str(Dir('#')))if GetOption('target') == 'vsc':from vsc import GenerateVSCodeGenerateVSCode(Env)if GetOption('target') == 'cdk':from cdk import CDKProjectCDKProject('project.cdkproj', Projects)if GetOption('target') == 'ses':from ses import SESProjectSESProject(Env)def EndBuilding(target, program = None):import rtconfigneed_exit = FalseEnv['target'] = programEnv['project'] = Projectsif hasattr(rtconfig, 'BSP_LIBRARY_TYPE'):Env['bsp_lib_type'] = rtconfig.BSP_LIBRARY_TYPEif hasattr(rtconfig, 'dist_handle'):Env['dist_handle'] = rtconfig.dist_handleEnv.AddPostAction(target, rtconfig.POST_ACTION)# Add addition clean filesClean(target, 'cconfig.h')Clean(target, 'rtua.py')Clean(target, 'rtua.pyc')if GetOption('target'):GenTargetProject(program)BSP_ROOT = Dir('#').abspathif GetOption('make-dist') and program != None:from mkdist import MkDistMkDist(program, BSP_ROOT, Rtt_Root, Env)if GetOption('make-dist-strip') and program != None:from mkdist import MkDist_StripMkDist_Strip(program, BSP_ROOT, Rtt_Root, Env)need_exit = Trueif GetOption('cscope'):from cscope import CscopeDatabaseCscopeDatabase(Projects)if not GetOption('help') and not GetOption('target'):if not os.path.exists(rtconfig.EXEC_PATH):print ("Error: the toolchain path (" + rtconfig.EXEC_PATH + ") is not exist, please check 'EXEC_PATH' in path or rtconfig.py.")need_exit = Trueif need_exit:exit(0)def SrcRemove(src, remove):if not src:returnsrc_bak = src[:]if type(remove) == type('str'):if os.path.isabs(remove):remove = os.path.relpath(remove, GetCurrentDir())remove = os.path.normpath(remove)for item in src_bak:if type(item) == type('str'):item_str = itemelse:item_str = item.rstr()if os.path.isabs(item_str):item_str = os.path.relpath(item_str, GetCurrentDir())item_str = os.path.normpath(item_str)if item_str == remove:src.remove(item)else:for remove_item in remove:remove_str = str(remove_item)if os.path.isabs(remove_str):remove_str = os.path.relpath(remove_str, GetCurrentDir())remove_str = os.path.normpath(remove_str)for item in src_bak:if type(item) == type('str'):item_str = itemelse:item_str = item.rstr()if os.path.isabs(item_str):item_str = os.path.relpath(item_str, GetCurrentDir())item_str = os.path.normpath(item_str)if item_str == remove_str:src.remove(item)def GetVersion():import SCons.cppimport stringrtdef = os.path.join(Rtt_Root, 'include', 'rtdef.h')# parse rtdef.h to get RT-Thread versionprepcessor = PatchedPreProcessor()f = open(rtdef, 'r')contents = f.read()f.close()prepcessor.process_contents(contents)def_ns = prepcessor.cpp_namespaceversion = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_VERSION']))subversion = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_SUBVERSION']))if 'RT_REVISION' in def_ns:revision = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_REVISION']))return '%d.%d.%d' % (version, subversion, revision)return '0.%d.%d' % (version, subversion)def GlobSubDir(sub_dir, ext_name):import osimport globdef glob_source(sub_dir, ext_name):list = os.listdir(sub_dir)src = glob.glob(os.path.join(sub_dir, ext_name))for item in list:full_subdir = os.path.join(sub_dir, item)if os.path.isdir(full_subdir):src += glob_source(full_subdir, ext_name)return srcdst = []src = glob_source(sub_dir, ext_name)for item in src:dst.append(os.path.relpath(item, sub_dir))return dstdef PackageSConscript(package):from package import BuildPackagereturn BuildPackage(package)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。