2.6 rt-thread实操 SConstruct解析

SConstruct 是 SCons 构建系统的顶层构建脚本,类似于 Makefile 在 make 工具中的作用。在 RT-Thread 项目中,SConstruct 文件通常位于 BSP(板级支持包)目录的根目录下,负责整个项目的构建过程。

下面总结 SConstruct 脚本的主要作用:

1. **初始化构建环境**:

- 设置工具链(编译器、链接器、汇编器等)及其编译选项。

- 设置环境变量,特别是将工具链路径添加到系统的 PATH 中,确保构建时能够找到正确的工具。

2. **加载配置**:

- 通过导入 `rtconfig` 模块(通常来自 `rtconfig.py` 文件)获取目标硬件平台的配置,如芯片架构、编译器类型、编译选项等。

3. **平台特定调整**:

- 根据不同的编译工具链(如 IAR、GCC、Keil 等)进行特定的配置调整。例如,针对 IAR 编译器重写编译命令。

4. **设置全局变量**:

- 导出全局变量(如 `RTT_ROOT`、`rtconfig`、`SDK_LIB` 等)给子目录的构建脚本(SConscript)使用。

5. **准备构建**:

- 调用 `PrepareBuilding` 函数(通常定义在 `$RTT_ROOT/building.py` 中)来初始化 RT-Thread 内核的构建环境,并生成内核相关的目标文件列表。

6. **包含其他构建脚本**:

- 通过 `SConscript` 函数调用其他子目录的构建脚本(通常是 `SConscript` 文件),例如:

- 芯片外设库(如 STM32L4xx_HAL 库)

- 硬件驱动(如 HAL_Drivers)

- 应用程序代码

- 将这些子目录构建生成的目标文件合并到主目标列表中。

7. **执行构建**:

- 调用 `DoBuilding` 函数(通常定义在 `$RTT_ROOT/building.py` 中)执行实际的构建过程,生成目标文件(如可执行文件、静态库等)。

8. **构建目录管理**:

- 通过 `variant_dir` 参数指定中间文件和目标文件的输出目录(通常为 `build` 目录),保持源码目录的整洁。

9. **自定义构建选项**:

- 支持通过 `rtconfig.py` 或命令行参数自定义构建选项,如优化级别、调试信息、宏定义等。

10. **多平台支持**:

- 通过条件判断(如 `if rtconfig.PLATFORM in ['iccarm']`)对不同平台进行适配。

在 RT-Thread 的 BSP 中,SConstruct 脚本是构建过程的入口,它组织内核、驱动、库和应用程序的编译,并最终链接成固件。

示例中的 SConstruct 脚本主要完成以下步骤:

1. 初始化环境(使用 MinGW 工具链,并设置各种编译工具和标志)。

2. 针对 IAR 编译器进行特殊处理。

3. 导出全局变量(RTT_ROOT, rtconfig)。

4. 确定库文件路径(SDK_LIB)。

5. 准备内核构建(PrepareBuilding)。

6. 设置使用的 HAL 库类型(如 STM32L4xx_HAL)。

7. 包含 HAL 库和驱动的构建脚本(通过 SConscript 函数)。

8. 执行构建(DoBuilding)。

通过这样的组织,SConstruct 脚本能够灵活地适应不同的硬件平台和工具链,实现整个项目的自动化构建。

每个工程都有一个唯一一个SConstruct脚本,是python语法,用来管理所有的SConscript脚本的。

image

 开头几个import为导入几个模块。python中就是类似类的对象,可以直接访问这个对象的成员和方法。

os.getenv,是python标准库中os模块提供的方法,用于读取操作系统的环境变量。

os.path.normpath,是python标准库中os.path模块的一个方法,用于规范会路径字符串,消除其中的冗余元素,如.代表当前目录,...代表父目录,这个函数返回一个规范化的路径字符串,使得该路径指向与原路径相同的位置,但表示形式更加简洁。

image

 

image

os.path.join函数,是python标准库提供的一个路径拼接函数,将两个参数值的路径拼接起来形成一个完成的路径,他会根据操作系统的情况自动选择用/还是\等进行自动拼接。

 sys.path决定了python再导入模块时的搜索顺序,所以sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]的目的,是为了让RTT+tools这个路径下的东西都可以作为导入python导入模块时使用。

rtconfig.TARGET_EXT指的实际上是rtconfig.py这个python模块中的TARGET_EXT变量值,是根据不同系统不同编译器rtconfig.py文件中复制的scons编译程序后的执行文件的后缀名。

image

 

image

 

### 1. `DefaultEnvironment(tools=[])`

- **作用**:设置SCons的默认环境。这里使用一个空的工具列表(`tools=[]`)来初始化默认环境。

- **解释**:SCons在构建时会使用一个默认的构造环境(construction environment)。通过调用`DefaultEnvironment`并传入`tools=[]`,我们创建了一个没有任何构建工具的默认环境。这样做可能是为了避免SCons自动检测系统默认的工具链(如gcc、clang等),从而让我们可以完全自定义构建环境。这在跨平台构建或需要精确控制工具链时非常有用。

### 2. 创建自定义环境:`env = Environment(...)`

- **作用**:创建一个新的构造环境(construction environment),并指定构建工具及其参数。

- **参数详解**:

- `tools = ['mingw']`:指定使用名为'mingw'的工具。这个工具是SCons内置的,用于支持MinGW(Minimalist GNU for Windows)工具链。它会根据MinGW的工具设置一些默认的行为。

- `AS = rtconfig.AS`:汇编器(Assembler)的可执行文件名或路径,从`rtconfig`模块中获取(`rtconfig`是RT-Thread的配置模块)。

- `ASFLAGS = rtconfig.AFLAGS`:汇编器的编译选项(flags)。

- `CC = rtconfig.CC`:C编译器的可执行文件名或路径。

- `CFLAGS = rtconfig.CFLAGS`:C编译器的编译选项。

- `AR = rtconfig.AR`:归档工具(Archiver,用于创建静态库)的可执行文件名或路径。

- `ARFLAGS = '-rc'`:归档工具的选项,`-rc`表示替换已存在的文件并创建新的归档(如果不存在)。

- `CXX = rtconfig.CXX`:C++编译器的可执行文件名或路径。

- `CXXFLAGS = rtconfig.CXXFLAGS`:C++编译器的编译选项。

- `LINK = rtconfig.LINK`:链接器的可执行文件名或路径。

- `LINKFLAGS = rtconfig.LFLAGS`:链接器的选项。

### 3. `env.PrependENVPath('PATH', rtconfig.EXEC_PATH)`

- **作用**:将`rtconfig.EXEC_PATH`添加到环境变量`PATH`的最前面。

- **解释**:

- `PrependENVPath`是SCons环境的一个方法,用于修改构造环境中的环境变量。

- 这里修改的是`PATH`环境变量,将`rtconfig.EXEC_PATH`(通常是工具链的路径,比如交叉编译器的路径)添加到`PATH`的最前面。

- 这样做的目的是确保在后续构建过程中,SCons能够优先使用`rtconfig.EXEC_PATH`路径下的工具(如gcc、ar、ld等),而不是系统默认路径下的工具。这对于使用特定的交叉编译工具链非常重要。

image

 同理这些代码就好理解了,是判断rtconfig.py模块中PLATFORM的平台如果是iccarm,则替换env的几个环境变量值。最后导出`RTT_ROOT`(RT-Thread根目录)和`rtconfig`(配置模块)变量,以便在子SConscript脚本中使用。

 

image

获取当前目录绝对路径(即SDK_ROOT)

- 如果当前目录下有`libraries`目录,则使用`$SDK_ROOT/libraries`;否则使用上级目录下的`libraries`(这样设计可能是为了支持多级目录结构)。

- 将库路径`SDK_LIB`导出,供子脚本使用

image

 PrepareBuilding是rt-thread下tools目录下的building.py模块中的方法

image

 

image

 

image

 

image

 

image

 

image

 

posted @ 2025-07-30 13:28  _小溢  阅读(102)  评论(0)    收藏  举报