def IARPath(): import rtconfig # backup environ old_environ = os.environ os.environ['RTT_CC'] = 'iar' utils.ReloadModule(rtconfig) # get iar path path = rtconfig.EXEC_PATH # restore environ os.environ = old_environ utils.ReloadModule(rtconfig) return path
def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components=[]): import rtconfig global BuildOptions global Projects global Env global 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/makefile/eclipse' ) 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 = env Rtt_Root = os.path.abspath(root_directory) # make an absolute root directory RTT_ROOT = Rtt_Root Export('RTT_ROOT') # set RTT_ROOT in ENV Env['RTT_ROOT'] = Rtt_Root # set BSP_ROOT in ENV Env['BSP_ROOT'] = Dir('#').abspath sys.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'), 'makefile': ('gcc', 'gcc'), 'eclipse': ('gcc', 'gcc'), 'ses': ('gcc', 'gcc') } tgt_name = GetOption('target') if tgt_name: # --target will change the toolchain settings which clang-analyzer is # depend on if 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_TOOL utils.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 failed if 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.py del os.environ['RTT_EXEC_PATH'] utils.ReloadModule(rtconfig) # add compability with Keil MDK 4.6 which changes the directory of armcc.exe if 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 flags env['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 spawn if env['PLATFORM'] == 'win32': win32_spawn = Win32Spawn() win32_spawn.env = env env['SPAWN'] = win32_spawn.spawn if env['PLATFORM'] == 'win32': os.environ['PATH'] = rtconfig.EXEC_PATH + ";" + os.environ['PATH'] else: os.environ['PATH'] = rtconfig.EXEC_PATH + ":" + os.environ['PATH'] # add program path env.PrependENVPath('PATH', rtconfig.EXEC_PATH) # add rtconfig.h/BSP path into Kernel group DefineGroup("Kernel", [], [], CPPPATH=[str(Dir('#').abspath)]) # add library build action act = SCons.Action.Action(BuildLibInstallAction, 'Install compiled library... $TARGET') bld = Builder(action=act) Env.Append(BUILDERS={'BuildLib': bld}) # parse rtconfig.h to get used component PreProcessor = PatchedPreProcessor() f = open('rtconfig.h', 'r') contents = f.read() f.close() PreProcessor.process_contents(contents) BuildOptions = PreProcessor.cpp_namespace if GetOption('clang-analyzer'): # perform what scan-build does env.Replace( CC='ccc-analyzer', CXX='c++-analyzer', # skip as and link LINK='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 messages env['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 file GenCconfigFile(env, BuildOptions) # auto append '_REENT_SMALL' when using newlib 'nano.specs' option if rtconfig.PLATFORM == 'gcc' and str( env['LINKFLAGS']).find('nano.specs') != -1: env.AppendUnique(CPPDEFINES=['_REENT_SMALL']) if GetOption('genconfig'): from genconf import genconfig genconfig() 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 menuconfig menuconfig(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_silent pyconfig_silent(Rtt_Root) exit(0) elif GetOption('pyconfig'): from menuconfig import pyconfig pyconfig(Rtt_Root) exit(0) configfn = GetOption('useconfig') if configfn: from menuconfig import mk_rtconfig mk_rtconfig(configfn) exit(0) if not GetOption('verbose'): # override the default verbose command string env.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 script objs = SConscript('SConscript', variant_dir=bsp_vdir, duplicate=0) # include kernel objs.extend( SConscript(Rtt_Root + '/src/SConscript', variant_dir=kernel_vdir + '/src', duplicate=0)) # include libcpu if not has_libcpu: objs.extend( SConscript(Rtt_Root + '/libcpu/SConscript', variant_dir=kernel_vdir + '/libcpu', duplicate=0)) # include components objs.extend( SConscript(Rtt_Root + '/components/SConscript', variant_dir=kernel_vdir + '/components', duplicate=0, exports='remove_components')) return objs