注: 对于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 + [os.path.join(RTT_ROOT, 'tools')]
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 = ['mingw'],
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 = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map'])
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 + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread-stm32.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
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 = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map'])
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/
shlly 2015-4-2 12:03