热度 31
2015-3-26 22:53
17451 次阅读|
1 个评论
scons的构建文件名称是统一的都称为SConstruct。其是scons所接受的编译脚本主文件。当然为了方便目录的组织,也允许在各个目录下面存放SConscript, 然后最上面SConstruct收集这些SConscript组织成为一个大的构建文件。 这里以bsp/stm32f10x为例予以介绍,其SConstruct文件为: 注: 对于RT-Thread的BSP下的SConstruct文件来说,此文件有些共同的部分。共同部分已高亮为红色。 import os import sys import rtconfig if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') sys.path = sys.path + from building import * 注释:RTT_ROOT即代表了RT-Thread源码包的路径,以我的系统为例,我将RT-Thread源码解压到D:\rt-thread\下,则上面代码就会设定RTT_ROOT = 'D:\rt-thread\' TARGET = 'rtthread-stm32.' + rtconfig.TARGET_EXT 注释:这一句用来设定编译生成的可执行文件的名称,比如是hex,bin或者是elf,还是axf(MDK编译器生成的具有调试信息的可执行文件名称,跟gcc下的elf类似,兼容) rtconfig.TARGET_EXE是指在rtconfig.py中定义的TARGET_EXT,在rtconfig.py中,可以看到有多个TARGET_EXT定义,其含义为目标文件的扩展名。 当TARGET_EXT为'axf'时,最后就会生成的文件为'rtthread-stm32.axf' env = Environment(tools = , AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, AR = rtconfig.AR, ARFLAGS = '-rc', LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) if rtconfig.PLATFORM == 'iar': env.Replace(CCCOM = ) env.Replace(ARFLAGS = ) env.Replace(LINKCOM = ) Export('RTT_ROOT') Export('rtconfig') # prepare building environment objs = PrepareBuilding(env, RTT_ROOT) 注释: PrepareBuilding是一个python函数,它是在tools/目录下的脚本文件中定义的,其作用正如其名所示,用于完成编译前的准备工作。 # STM32 firemare library building script objs = objs + SConscript( GetCurrentDir() + '/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) 注释:能够让一个SConstruct文件再关联一个新的组件(用户自行定义的组件,而不是RT-Thread系统的组件,此处是STM32的固件库)。 这里SConscript函数SCons内置的函数,它可以读入一个新的SConscript文件,并将SConscript文件中所指明的源码加入编译列表中来。 SConscript文件和下节的组件编译文件实际是一样的,因为可以把BSP看成一个组件Group(在工程文件中它也确实是一个Group),所以这个组件所对应的编译脚本就是SConscript。 SConscript函数的参数包括三个: 第一个是SConscript路径,GetCurrentDir()返回当前文件所处的路径,即SConstruct文件所在的目录,可以看到此目录下存在一个Libraries目录,并且其目录下存在一个SConscript文件,我们将子下一节介绍SConscript文件是介绍它。 variant_dir则指定生成的目标文件的存放路径,这里即为'build/bsp/Libraries',用户当然可以根据自己的喜好做修改。 duiplicate 的作用是设定是否拷贝或链接源文件到variant_dir if GetDepend('RT_USING_RTGUI'): objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) 注释:上述代码的意思是,如果在rtconfig.h中定义了宏RT_USING_RTGUI,那么就执行SConscript函数,将rt-thread/examples/gui下的C源码加入编译。 GetDepend函数是python函数,在tools/目录下的脚本文件中定义,它会从rtconfig.h文件读取组件配置信息,其参数为rtconfig.h中的宏名。 # build program env.Program(TARGET, objs) # end building EndBuilding(TARGET) 全部代码: import os import sys import rtconfig if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') sys.path = sys.path + from building import * TARGET = 'rtthread-stm32.' + rtconfig.TARGET_EXT env = Environment(tools = , AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, AR = rtconfig.AR, ARFLAGS = '-rc', LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) if rtconfig.PLATFORM == 'iar': env.Replace(CCCOM = ) env.Replace(ARFLAGS = ) env.Replace(LINKCOM = ) Export('RTT_ROOT') Export('rtconfig') # prepare building environment objs = PrepareBuilding(env, RTT_ROOT) # STM32 firemare library building script objs = objs + SConscript( GetCurrentDir() + '/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) if GetDepend('RT_USING_RTGUI'): objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) # build program env.Program(TARGET, objs) # end building EndBuilding(TARGET) 参考资料来源:http://www.rt-thread.org/