Scons和Kconfig快速入门

SifliSDK提供了一个Env配置工具,这个工具里就已经带有SCons和Python,因此在Windows平台使用SCons并不需要安装。SifliSDK在scons基础上添加了一些脚本库函数,简化用户的项目配置。

1. 项目文件结构

SCons使用SConscript和SConstruct文件来组织源码结构,通常来说一个项目只有一 SConstruct,在项目根目录中,但是会有多个SConscript。一般情况下,每个存放有源代码的子目录下都会放置一个SConscript。用户可以参考 example\uart\project\ec-lbxxx ,看到项目文件结构。

SifliSDK 为每个项目单独创建了一个名为 rtconfig.py 的文件。因此每一个项目目录下都会存在下面三个文件:rtconfig.pySConstructSConscript ,它们控制项目的编译。一个项目中只有一个 SConstruct 文件,但是却可能会有多个 SConscript 文件,可以说 SConscript 文件是组织源码的主力军。

SifliSDK使用menuconfig来配置项目,每个项目有一个Kconfig,在项目根目录中,作为配置选项的起点,配置完成后会在项目根目录生成 .configrtconfig.h ,分别用于Scons脚本和c文件。

SifliSDK大部分源码文件夹下也存在 SConscript 文件,这些文件会被项目根目录下的 SConscript 文件 “找到” 从而将 .config/rtconfig.h 中定义的宏对应的源代码加入到编译器中来。

SCons编译项目首先执行的是 SConstruct. 在用户项目的 Sconstruct 可以配置一些项目的选项,和menuconfig工具生成的项目配置.config配合, SifliEnv()函数会设置相应的默认编译选项。用户如果需要强制修改相关编译/链接的选项,可以改变Environment()函数中相应的参数。

3. SCons的基本功能

在Env工具中直接输入scons命令直接编译项目,默认使用ARM CLANG编译器。SifliSDK根目录有 set_env.bat , 里面会设定编译器目录。

如果需要自己制定编译器,可以在修改 set_env.bat 里面的命令指定:

set RTT_CC = keil
set RTT_EXEC = C:/Keilv5

scons命令 该命令不仅可以完成基本的编译,还可以生成MDK/IAR/VS 工程,在后边增加不同参数可以实现不同效果。

  • -s 参数,不会打印具体的内部命令。

  • -c 参数,清除编译目标,清除临时文件和目标文件。

  • --target=XXX 参数,如果使用mdk/iar来进行项目开发,当修改了 rtconfig.h 打开或者关闭某些组件时,需要使用该参数来重新生成对应的定制化工程。然后在mdk/iar中进行编译下载。

警告

注意:要生成MDK或者IAR的工程文件,前提条件是项目目录存在一个工程模版文件,然后scons才会根据这份模版文件加入相关的源码,头文件搜索路径,编译参数,链接参数等。而至于这个工程是针对哪颗芯片的,则直接由这份工程模版文件指定。所以大多数情况下,这个模版文件是一份空的工程文件,用于辅助 SCons 生成 project.uvprojx 或者 project.eww 。为了方便客户,如果没有找到 project.uvprojx , SiFliSDK会使用一份默认的模板用于生成 project.uvprojx ,用户如果不想使用默认的模板(例如添加自己的编译选项),可以将 SifliSDK\tools\build\template 下面的 template.uvprojx 拷贝到项目目录,作为自己的项目模板,添加自己特定的改变。

  • -jN 参数,多线程编译目标,在多核计算机上可以使用此命令加快编译速度。一般来说一颗 cpu 核心可以支持 2 个线程。双核机器上使用scons -j4命令即可。

  • --verbose参数,默认情况下,使用scons命令编译的输出不会显示编译参数,使用该参数,会显示编译参数。

4. SCons 内置函数

如果想要将自己的一些源代码加入到 SCons 编译环境中,一般可以创建或修改已有 SConscript 文件。

SConscript 文件可以控制源码文件的加入,并且可以指定文件的Group(与MDK/IAR等IDE中的Group的概念类似)。

SCons提供了很多内置函数可以帮助我们快速添加源码程序,利用这些函数,再配合一些简单的Python语句我们就能随心所欲向项目中添加或者删除源码。下面将简单介绍一些常用函数。实际上每个 SConscript 文件就是一个python文件。

  • GetCurrentDir() 函数,获取当前路径。

  • Glob('*.c')函数,获取当前目录下所有C文件。修改参数中的后缀,可以匹配当前目录下的所有某类型的文件。

  • GetDepend(macro)函数,该函数定义在tools目录下的脚本文件中,它会从 rtconfig.h 文件读取配置信息,其参数为 rtconfig.h 中的宏名。如果 rtconfig.h 打开了某个宏,则这个方法(函数)返回真,否则返回假。

  • Split(str)函数,将字符串str分割成一个列表list。

  • DefineGroup(name, src, depend,**parameters)函数,这是基于 SCons 扩展的一个方法(函数)。DefineGroup用于定义一个组件。组件可以是一个目录(下的文件或子目录),也是后续一些IDE工程文件中的一个Group或文件夹。parameter可以添加:

    • LIBS=<some.lib> 将特定lib链接进入项目

    • LIBPATH=<some path> 在特定目录中放入.lib

    • LIBRARY=<some.lib> 将所有group 中源代码编译链接,生成 .lib

    • INSTALL_PATH=<some path> 将生成的.lib安装到特定目录中

    • CCFLAGS=<more CC flags> 添加编译选项

    • CPPPATH=<some folder> 添加C语言头文件搜索目录

    • CPPDEFINES=<more macro> 添加C语言宏定义

    • LINKFLAGS=<more link flags> 添加链接选项

    • ASFLAGS=<more assembly flags> 添加汇编选项