Explorar o código

[Tools] Add documents for tools script; Add NG for tools

bernard hai 1 mes
pai
achega
a65efe648c

+ 162 - 0
tools/docs/README.md

@@ -0,0 +1,162 @@
+# RT-Thread 构建系统文档
+
+欢迎使用RT-Thread构建系统文档。本文档集详细介绍了RT-Thread基于SCons的构建系统的使用方法和技术原理。
+
+## 文档目录
+
+### 📚 用户指南
+
+1. **[构建系统使用指南](构建系统使用指南.md)**
+   - 快速开始
+   - 命令行选项详解
+   - 工具链配置
+   - 项目生成
+   - 软件包管理
+   - 高级功能
+   - 常见问题解答
+
+2. **[SConscript编写指南](SConscript编写指南.md)**
+   - 基础语法
+   - 常用模式
+   - 高级技巧
+   - 最佳实践
+   - 示例集合
+
+### 🔧 技术文档
+
+3. **[构建系统技术原理](构建系统技术原理.md)**
+   - 系统架构设计
+   - 核心模块分析
+   - 构建流程详解
+   - 依赖管理机制
+   - 工具链适配层
+   - 项目生成器架构
+   - 扩展机制
+
+## 快速导航
+
+### 常用命令
+
+```bash
+# 基础编译
+scons                    # 默认编译
+scons -j8               # 8线程并行编译
+scons -c                # 清理编译产物
+
+# 配置管理
+menuconfig              # 图形化配置
+scons --pyconfig       # Python脚本配置
+
+# 项目生成
+scons --target=mdk5    # 生成Keil MDK5项目
+scons --target=iar     # 生成IAR项目
+scons --target=vsc     # 生成VS Code项目
+scons --target=cmake   # 生成CMake项目
+
+# 软件包管理
+pkgs --update          # 更新软件包
+pkgs --list           # 列出已安装包
+```
+
+### 核心概念
+
+- **SConstruct**: BSP根目录的主构建脚本
+- **SConscript**: 各个组件/目录的构建脚本
+- **rtconfig.py**: 工具链和平台配置
+- **rtconfig.h**: RT-Thread功能配置
+- **DefineGroup**: 定义组件的核心函数
+- **GetDepend**: 检查依赖的核心函数
+
+## 构建系统架构图
+
+```
+┌─────────────────────────────────────┐
+│          用户命令 (scons)           │
+└──────────────┬──────────────────────┘
+               │
+┌──────────────▼──────────────────────┐
+│         SConstruct (主脚本)         │
+│     ┌─────────────────────┐        │
+│     │   PrepareBuilding()  │        │
+│     │   环境初始化         │        │
+│     └──────────┬──────────┘        │
+└────────────────┼───────────────────┘
+                 │
+┌────────────────▼────────────────────┐
+│         building.py                 │
+│   ┌──────────┬──────────┐          │
+│   │ 组件收集 │ 依赖处理 │          │
+│   └──────────┴──────────┘          │
+└─────────────────────────────────────┘
+                 │
+        ┌────────┴────────┐
+        │                 │
+┌───────▼──────┐ ┌────────▼────────┐
+│  SConscript  │ │   rtconfig.h    │
+│  组件脚本    │ │   功能配置      │
+└──────────────┘ └─────────────────┘
+```
+
+## 主要特性
+
+✅ **多工具链支持**
+- GCC (ARM/RISC-V/x86)
+- Keil MDK (ARMCC/ARMClang)
+- IAR
+- Visual Studio
+
+✅ **灵活的配置系统**
+- Kconfig图形配置
+- 条件编译支持
+- 本地编译选项
+
+✅ **丰富的项目生成器**
+- IDE项目文件生成
+- CMake支持
+- Makefile生成
+- VS Code配置
+
+✅ **模块化设计**
+- 组件独立构建
+- 清晰的依赖管理
+- 可扩展架构
+
+## 开发工作流
+
+```mermaid
+graph LR
+    A[配置系统] --> B[编写代码]
+    B --> C[构建项目]
+    C --> D[调试运行]
+    D --> E{是否完成?}
+    E -->|否| B
+    E -->|是| F[发布]
+    
+    A1[menuconfig] -.-> A
+    C1[scons] -.-> C
+    C2[IDE项目] -.-> C
+```
+
+## 相关链接
+
+- [RT-Thread官网](https://www.rt-thread.org)
+- [RT-Thread GitHub](https://github.com/RT-Thread/rt-thread)
+- [SCons官方文档](https://scons.org/documentation.html)
+
+## 贡献指南
+
+如果您发现文档中的错误或有改进建议,欢迎:
+
+1. 在GitHub上提交Issue
+2. 提交Pull Request
+3. 在RT-Thread社区论坛反馈
+
+## 版本信息
+
+- 文档版本:1.0.0
+- 更新日期:2024-01
+- 适用版本:RT-Thread 4.1.0+
+
+---
+
+**注意**:本文档基于RT-Thread最新版本编写,部分功能可能需要特定版本支持。使用前请确认您的RT-Thread版本。

+ 948 - 0
tools/docs/SConscript编写指南.md

@@ -0,0 +1,948 @@
+# RT-Thread SConscript 编写指南
+
+## 目录
+
+1. [概述](#概述)
+2. [基础语法](#基础语法)
+3. [常用模式](#常用模式)
+4. [高级技巧](#高级技巧)
+5. [最佳实践](#最佳实践)
+6. [示例集合](#示例集合)
+7. [常见问题](#常见问题)
+
+## 概述
+
+SConscript是RT-Thread构建系统中的模块构建脚本,每个组件或目录都可以有自己的SConscript文件。本指南将详细介绍如何编写高质量的SConscript文件。
+
+### SConscript在构建系统中的位置
+
+```
+项目根目录/
+├── SConstruct          # 主构建脚本
+├── applications/
+│   └── SConscript      # 应用层构建脚本
+├── drivers/
+│   └── SConscript      # 驱动层构建脚本
+└── components/
+    ├── SConscript      # 组件主脚本
+    └── finsh/
+        └── SConscript  # 子组件脚本
+```
+
+## 基础语法
+
+### 1. 基本结构
+
+```python
+# 导入构建模块
+from building import *
+
+# 获取当前目录
+cwd = GetCurrentDir()
+
+# 定义源文件
+src = ['main.c', 'app.c']
+
+# 定义头文件路径
+CPPPATH = [cwd]
+
+# 定义组
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+# 返回组对象
+Return('group')
+```
+
+### 2. 导入building模块
+
+```python
+from building import *
+```
+
+这行代码导入了RT-Thread构建系统的所有函数,包括:
+- `GetCurrentDir()` - 获取当前目录
+- `DefineGroup()` - 定义组件组
+- `GetDepend()` - 检查依赖
+- `Glob()` - 文件通配符匹配
+- `SrcRemove()` - 移除源文件
+- `DoBuilding()` - 执行构建
+
+### 3. 源文件定义
+
+#### 手动指定文件列表
+```python
+src = ['file1.c', 'file2.c', 'file3.c']
+```
+
+#### 使用通配符
+```python
+src = Glob('*.c')           # 当前目录所有.c文件
+src = Glob('src/*.c')       # src子目录所有.c文件
+src = Glob('**/*.c')        # 递归所有子目录的.c文件
+```
+
+#### 混合使用
+```python
+src = ['main.c'] + Glob('drivers/*.c')
+```
+
+### 4. 条件编译
+
+#### 基于宏定义
+```python
+src = ['common.c']
+
+if GetDepend('RT_USING_SERIAL'):
+    src += ['serial.c']
+
+if GetDepend('RT_USING_I2C'):
+    src += ['i2c.c']
+```
+
+#### 基于平台
+```python
+import rtconfig
+
+if rtconfig.PLATFORM == 'gcc':
+    src += ['gcc_specific.c']
+elif rtconfig.PLATFORM == 'armcc':
+    src += ['keil_specific.c']
+```
+
+### 5. 移除文件
+
+```python
+src = Glob('*.c')
+SrcRemove(src, ['test.c', 'debug.c'])  # 移除不需要的文件
+```
+
+## 常用模式
+
+### 1. 简单组件模式
+
+最基础的SConscript模式:
+
+```python
+from building import *
+
+src = Glob('*.c')
+CPPPATH = [GetCurrentDir()]
+
+group = DefineGroup('MyComponent', src, depend = ['RT_USING_MYCOMPONENT'], 
+                    CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 2. 条件编译模式
+
+根据配置选项包含不同的源文件:
+
+```python
+from building import *
+
+src = ['core.c']
+CPPPATH = [GetCurrentDir()]
+
+# 功能模块条件编译
+if GetDepend('MYCOMPONENT_USING_FEATURE_A'):
+    src += ['feature_a.c']
+
+if GetDepend('MYCOMPONENT_USING_FEATURE_B'):
+    src += ['feature_b.c']
+
+# 平台相关代码
+if rtconfig.PLATFORM == 'gcc':
+    src += ['port_gcc.c']
+elif rtconfig.PLATFORM == 'armcc':
+    src += ['port_keil.c']
+elif rtconfig.PLATFORM == 'iccarm':
+    src += ['port_iar.c']
+
+group = DefineGroup('MyComponent', src, depend = ['RT_USING_MYCOMPONENT'], 
+                    CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 3. 多目录组织模式
+
+处理复杂的目录结构:
+
+```python
+from building import *
+
+cwd = GetCurrentDir()
+
+# 源文件来自多个目录
+src = Glob('src/*.c')
+src += Glob('port/*.c')
+src += Glob('hal/*.c')
+
+# 多个头文件路径
+CPPPATH = [
+    cwd,
+    cwd + '/include',
+    cwd + '/internal',
+    cwd + '/port'
+]
+
+# 根据配置添加特定目录
+if GetDepend('RT_USING_LWIP'):
+    src += Glob('lwip/*.c')
+    CPPPATH += [cwd + '/lwip']
+
+group = DefineGroup('Network', src, depend = ['RT_USING_NETWORK'], 
+                    CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 4. 递归子目录模式
+
+自动处理所有子目录的SConscript:
+
+```python
+import os
+from building import *
+
+objs = []
+cwd = GetCurrentDir()
+
+# 获取所有子目录
+list = os.listdir(cwd)
+
+# 需要跳过的目录
+skip_dirs = ['test', 'doc', 'examples', '.git']
+
+for d in list:
+    path = os.path.join(cwd, d)
+    # 检查是否是目录且包含SConscript
+    if os.path.isdir(path) and d not in skip_dirs:
+        if os.path.isfile(os.path.join(path, 'SConscript')):
+            objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')
+```
+
+### 5. 库文件链接模式
+
+链接预编译的库文件:
+
+```python
+from building import *
+import os
+
+cwd = GetCurrentDir()
+
+# 只包含必要的接口文件
+src = ['lib_interface.c']
+
+CPPPATH = [cwd + '/include']
+
+# 库文件配置
+LIBS = []
+LIBPATH = []
+
+# 根据架构选择库文件
+import rtconfig
+if rtconfig.ARCH == 'arm':
+    if rtconfig.CPU == 'cortex-m4':
+        LIBS += ['mylib_cm4']
+        LIBPATH += [cwd + '/lib/cortex-m4']
+    elif rtconfig.CPU == 'cortex-m3':
+        LIBS += ['mylib_cm3']
+        LIBPATH += [cwd + '/lib/cortex-m3']
+
+group = DefineGroup('MyLib', src, depend = ['RT_USING_MYLIB'], 
+                    CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH)
+
+Return('group')
+```
+
+## 高级技巧
+
+### 1. 本地编译选项
+
+为特定模块设置独立的编译选项:
+
+```python
+from building import *
+
+src = Glob('*.c')
+CPPPATH = [GetCurrentDir()]
+
+# 全局编译选项(影响依赖此组件的其他组件)
+CPPDEFINES = ['GLOBAL_DEFINE']
+
+# 本地编译选项(仅影响当前组件)
+LOCAL_CFLAGS = ''
+LOCAL_CPPDEFINES = ['LOCAL_DEFINE']
+LOCAL_CPPPATH = ['./private']
+
+# 根据编译器设置优化选项
+import rtconfig
+if rtconfig.PLATFORM == 'gcc':
+    LOCAL_CFLAGS += ' -O3 -funroll-loops'
+elif rtconfig.PLATFORM == 'armcc':
+    LOCAL_CFLAGS += ' -O3 --loop_optimization_level=2'
+
+group = DefineGroup('HighPerf', src, depend = ['RT_USING_HIGHPERF'],
+    CPPPATH = CPPPATH,
+    CPPDEFINES = CPPDEFINES,
+    LOCAL_CFLAGS = LOCAL_CFLAGS,
+    LOCAL_CPPDEFINES = LOCAL_CPPDEFINES,
+    LOCAL_CPPPATH = LOCAL_CPPPATH
+)
+
+Return('group')
+```
+
+### 2. 动态源文件生成
+
+在构建时生成源文件:
+
+```python
+from building import *
+import time
+
+def generate_version_file():
+    """生成版本信息文件"""
+    version_c = '''
+/* Auto-generated file, do not edit! */
+#include "version.h"
+
+const char *build_time = "%s";
+const char *version = "%s";
+''' % (time.strftime('%Y-%m-%d %H:%M:%S'), '1.0.0')
+    
+    with open('version_gen.c', 'w') as f:
+        f.write(version_c)
+
+# 生成文件
+generate_version_file()
+
+src = ['main.c', 'version_gen.c']
+CPPPATH = [GetCurrentDir()]
+
+group = DefineGroup('App', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 3. 复杂依赖处理
+
+处理复杂的依赖关系:
+
+```python
+from building import *
+
+src = []
+CPPPATH = [GetCurrentDir()]
+CPPDEFINES = []
+
+# 基础功能
+if GetDepend('RT_USING_DEVICE'):
+    src += ['device_core.c']
+    
+    # 串口驱动(依赖设备框架)
+    if GetDepend('RT_USING_SERIAL'):
+        src += ['serial.c']
+        
+        # 串口DMA(依赖串口驱动)
+        if GetDepend('RT_SERIAL_USING_DMA'):
+            src += ['serial_dma.c']
+            CPPDEFINES += ['SERIAL_USING_DMA']
+    
+    # SPI驱动(依赖设备框架)
+    if GetDepend('RT_USING_SPI'):
+        src += ['spi.c']
+        
+        # SPI DMA(依赖SPI驱动)
+        if GetDepend('RT_SPI_USING_DMA'):
+            src += ['spi_dma.c']
+
+# 错误检查
+if GetDepend('RT_SERIAL_USING_DMA') and not GetDepend('RT_USING_SERIAL'):
+    print('Error: RT_SERIAL_USING_DMA requires RT_USING_SERIAL!')
+    exit(1)
+
+group = DefineGroup('Drivers', src, depend = ['RT_USING_DEVICE'], 
+                    CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
+
+Return('group')
+```
+
+### 4. 平台特定实现
+
+根据不同平台包含不同实现:
+
+```python
+from building import *
+import rtconfig
+
+cwd = GetCurrentDir()
+src = ['common.c']
+CPPPATH = [cwd, cwd + '/include']
+
+# 架构相关目录映射
+arch_map = {
+    'arm': {
+        'cortex-m3': 'arm/cortex-m3',
+        'cortex-m4': 'arm/cortex-m4',
+        'cortex-m7': 'arm/cortex-m7',
+        'cortex-a': 'arm/cortex-a'
+    },
+    'risc-v': {
+        'rv32': 'riscv/rv32',
+        'rv64': 'riscv/rv64'
+    },
+    'x86': {
+        'i386': 'x86/i386',
+        'x86_64': 'x86/x86_64'
+    }
+}
+
+# 根据架构和CPU选择实现
+if hasattr(rtconfig, 'ARCH') and hasattr(rtconfig, 'CPU'):
+    arch = rtconfig.ARCH
+    cpu = rtconfig.CPU
+    
+    if arch in arch_map and cpu in arch_map[arch]:
+        port_dir = arch_map[arch][cpu]
+        port_src = Glob(port_dir + '/*.c')
+        port_src += Glob(port_dir + '/*.S')
+        src += port_src
+        CPPPATH += [cwd + '/' + port_dir]
+    else:
+        print('Warning: No port for %s - %s' % (arch, cpu))
+
+group = DefineGroup('MyDriver', src, depend = ['RT_USING_MYDRIVER'], 
+                    CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 5. 第三方库集成
+
+集成第三方库的模板:
+
+```python
+from building import *
+import os
+
+cwd = GetCurrentDir()
+
+# 第三方库路径
+lib_path = cwd + '/3rdparty/libfoo'
+
+# 检查库是否存在
+if not os.path.exists(lib_path):
+    print('Error: libfoo not found at', lib_path)
+    print('Please run: git submodule update --init')
+    Return('group')
+
+# 库源文件
+src = Glob(lib_path + '/src/*.c')
+
+# 移除不需要的文件
+SrcRemove(src, [
+    lib_path + '/src/test.c',
+    lib_path + '/src/example.c'
+])
+
+# 头文件路径
+CPPPATH = [
+    lib_path + '/include',
+    cwd + '/port'  # 移植层头文件
+]
+
+# 添加移植层
+src += Glob('port/*.c')
+
+# 配置宏定义
+CPPDEFINES = ['LIBFOO_RTOS_RTTHREAD']
+
+# 根据配置启用功能
+if GetDepend('LIBFOO_ENABLE_FLOAT'):
+    CPPDEFINES += ['LIBFOO_USE_FLOAT']
+
+if GetDepend('LIBFOO_ENABLE_STDIO'):
+    CPPDEFINES += ['LIBFOO_USE_STDIO']
+
+group = DefineGroup('libfoo', src, depend = ['RT_USING_LIBFOO'], 
+                    CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
+
+Return('group')
+```
+
+### 6. 条件导出符号
+
+根据配置导出不同的API:
+
+```python
+from building import *
+
+src = ['core.c']
+CPPPATH = [GetCurrentDir()]
+
+# API版本控制
+if GetDepend('RT_USING_MODULE_API_V2'):
+    src += ['api_v2.c']
+    CPPDEFINES = ['MODULE_API_VERSION=2']
+else:
+    src += ['api_v1.c']
+    CPPDEFINES = ['MODULE_API_VERSION=1']
+
+# 根据配置级别导出不同功能
+if GetDepend('MODULE_EXPERT_MODE'):
+    src += ['expert_api.c']
+    CPPDEFINES += ['EXPORT_EXPERT_API']
+
+group = DefineGroup('Module', src, depend = ['RT_USING_MODULE'], 
+                    CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
+
+Return('group')
+```
+
+## 最佳实践
+
+### 1. 文件组织原则
+
+```
+component/
+├── SConscript          # 主构建脚本
+├── Kconfig             # 配置选项
+├── README.md           # 组件说明
+├── include/            # 公开头文件
+│   └── component.h
+├── src/                # 源文件
+│   ├── core.c
+│   └── utils.c
+├── port/               # 平台相关代码
+│   ├── cortex-m/
+│   └── risc-v/
+└── examples/           # 示例代码
+    └── example.c
+```
+
+### 2. 依赖管理最佳实践
+
+```python
+from building import *
+
+# 1. 明确声明依赖
+REQUIRED_DEPS = ['RT_USING_DEVICE', 'RT_USING_HEAP']
+
+# 2. 检查必要依赖
+for dep in REQUIRED_DEPS:
+    if not GetDepend(dep):
+        print('Error: %s requires %s' % ('MyComponent', dep))
+        Return('group')
+
+# 3. 可选依赖
+src = ['core.c']
+
+# 可选功能
+OPTIONAL_FEATURES = {
+    'RT_MYCOMPONENT_USING_DMA': 'dma.c',
+    'RT_MYCOMPONENT_USING_INTERRUPT': 'interrupt.c',
+    'RT_MYCOMPONENT_USING_STATS': 'statistics.c'
+}
+
+for macro, file in OPTIONAL_FEATURES.items():
+    if GetDepend(macro):
+        src += [file]
+
+group = DefineGroup('MyComponent', src, depend = ['RT_USING_MYCOMPONENT'])
+Return('group')
+```
+
+### 3. 错误处理
+
+```python
+from building import *
+import os
+
+# 检查关键文件
+critical_files = ['config.h', 'version.h']
+for f in critical_files:
+    if not os.path.exists(f):
+        print('Error: Missing required file:', f)
+        # 返回空组,不中断整体构建
+        group = DefineGroup('MyComponent', [], depend = [''])
+        Return('group')
+
+# 检查工具链
+import rtconfig
+supported_toolchains = ['gcc', 'armcc', 'iar']
+if rtconfig.PLATFORM not in supported_toolchains:
+    print('Warning: Toolchain %s not tested' % rtconfig.PLATFORM)
+
+# 正常构建流程
+src = Glob('*.c')
+group = DefineGroup('MyComponent', src, depend = ['RT_USING_MYCOMPONENT'])
+Return('group')
+```
+
+### 4. 性能优化
+
+```python
+from building import *
+import os
+
+# 1. 缓存文件列表(避免重复扫描)
+_file_cache = {}
+
+def cached_glob(pattern):
+    if pattern not in _file_cache:
+        _file_cache[pattern] = Glob(pattern)
+    return _file_cache[pattern]
+
+# 2. 延迟加载(仅在需要时扫描)
+src = []
+if GetDepend('RT_USING_MYCOMPONENT'):
+    src = cached_glob('*.c')
+    
+    if GetDepend('RT_MYCOMPONENT_USING_EXTRA'):
+        src += cached_glob('extra/*.c')
+
+# 3. 避免深度递归(使用显式路径)
+# 不好的做法
+# src = Glob('**/*.c')  # 递归所有子目录
+
+# 好的做法
+src = Glob('*.c')
+src += Glob('core/*.c')
+src += Glob('hal/*.c')
+
+group = DefineGroup('MyComponent', src, depend = ['RT_USING_MYCOMPONENT'])
+Return('group')
+```
+
+### 5. 文档化
+
+```python
+"""
+SConscript for MyComponent
+
+This component provides [功能描述]
+
+Configuration:
+    RT_USING_MYCOMPONENT - Enable this component
+    RT_MYCOMPONENT_USING_DMA - Enable DMA support
+    RT_MYCOMPONENT_BUFFER_SIZE - Buffer size (default: 256)
+
+Dependencies:
+    - RT_USING_DEVICE (required)
+    - RT_USING_DMA (optional, for DMA support)
+"""
+
+from building import *
+
+# ... 构建脚本内容 ...
+```
+
+## 示例集合
+
+### 示例1:设备驱动SConscript
+
+```python
+from building import *
+
+cwd = GetCurrentDir()
+
+# 驱动源文件
+src = []
+CPPPATH = [cwd + '/../inc']
+
+# I2C驱动
+if GetDepend('RT_USING_I2C'):
+    src += ['drv_i2c.c']
+
+# SPI驱动
+if GetDepend('RT_USING_SPI'):
+    src += ['drv_spi.c']
+    
+    # QSPI支持
+    if GetDepend('RT_USING_QSPI'):
+        src += ['drv_qspi.c']
+
+# USB驱动
+if GetDepend('RT_USING_USB'):
+    src += ['drv_usb.c']
+    if GetDepend('RT_USING_USB_HOST'):
+        src += ['drv_usbh.c']
+    if GetDepend('RT_USING_USB_DEVICE'):
+        src += ['drv_usbd.c']
+
+# SDIO驱动
+if GetDepend('RT_USING_SDIO'):
+    src += ['drv_sdio.c']
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 示例2:网络组件SConscript
+
+```python
+from building import *
+
+cwd = GetCurrentDir()
+src = []
+CPPPATH = [cwd]
+
+# 网络接口层
+if GetDepend('RT_USING_NETDEV'):
+    src += Glob('netdev/*.c')
+    CPPPATH += [cwd + '/netdev']
+
+# SAL套接字抽象层
+if GetDepend('RT_USING_SAL'):
+    src += Glob('sal/src/*.c')
+    src += Glob('sal/socket/*.c')
+    CPPPATH += [cwd + '/sal/include']
+    
+    # AT指令支持
+    if GetDepend('SAL_USING_AT'):
+        src += Glob('sal/impl/af_inet_at.c')
+    
+    # LwIP支持
+    if GetDepend('SAL_USING_LWIP'):
+        src += Glob('sal/impl/af_inet_lwip.c')
+
+# AT指令框架
+if GetDepend('RT_USING_AT'):
+    src += Glob('at/src/*.c')
+    CPPPATH += [cwd + '/at/include']
+    
+    # AT Socket
+    if GetDepend('AT_USING_SOCKET'):
+        src += Glob('at/at_socket/*.c')
+
+group = DefineGroup('Network', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 示例3:文件系统SConscript
+
+```python
+from building import *
+
+cwd = GetCurrentDir()
+src = []
+CPPPATH = [cwd + '/include']
+
+# DFS框架
+if GetDepend('RT_USING_DFS'):
+    src += Glob('src/*.c')
+    
+    # ELM FatFS
+    if GetDepend('RT_USING_DFS_ELMFAT'):
+        src += Glob('filesystems/elmfat/*.c')
+        # FatFS版本选择
+        if GetDepend('RT_DFS_ELM_USE_LFN'):
+            src += ['filesystems/elmfat/ffunicode.c']
+    
+    # ROMFS
+    if GetDepend('RT_USING_DFS_ROMFS'):
+        src += ['filesystems/romfs/dfs_romfs.c']
+    
+    # DevFS
+    if GetDepend('RT_USING_DFS_DEVFS'):
+        src += ['filesystems/devfs/devfs.c']
+    
+    # NFS
+    if GetDepend('RT_USING_DFS_NFS'):
+        src += Glob('filesystems/nfs/*.c')
+        CPPPATH += [cwd + '/filesystems/nfs']
+
+group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], 
+                    CPPPATH = CPPPATH)
+
+Return('group')
+```
+
+### 示例4:使用package.json的SConscript
+
+```python
+from building import *
+import os
+import json
+
+cwd = GetCurrentDir()
+
+# 尝试使用package.json
+package_file = os.path.join(cwd, 'package.json')
+if os.path.exists(package_file):
+    # 使用自动构建
+    objs = BuildPackage(package_file)
+else:
+    # 手动构建
+    src = Glob('src/*.c')
+    CPPPATH = [cwd + '/include']
+    
+    # 读取配置
+    config_file = os.path.join(cwd, 'config.json')
+    if os.path.exists(config_file):
+        with open(config_file, 'r') as f:
+            config = json.load(f)
+            
+        # 根据配置添加源文件
+        for feature in config.get('features', []):
+            if GetDepend('RT_USING_' + feature.upper()):
+                src += Glob('src/%s/*.c' % feature)
+    
+    objs = DefineGroup('MyPackage', src, depend = ['RT_USING_MYPACKAGE'], 
+                       CPPPATH = CPPPATH)
+
+Return('objs')
+```
+
+## 常见问题
+
+### Q1: 如何调试SConscript?
+
+```python
+from building import *
+
+# 1. 打印调试信息
+print('Current directory:', GetCurrentDir())
+print('GetDepend RT_USING_XXX:', GetDepend('RT_USING_XXX'))
+
+# 2. 打印源文件列表
+src = Glob('*.c')
+print('Source files:', src)
+
+# 3. 条件调试输出
+if GetOption('verbose'):
+    print('Detailed debug info...')
+
+# 4. 检查环境变量
+import os
+print('RTT_ROOT:', os.getenv('RTT_ROOT'))
+```
+
+### Q2: 如何处理可选的依赖?
+
+```python
+from building import *
+
+src = ['core.c']
+
+# 可选依赖处理
+optional_deps = {
+    'RT_USING_SERIAL': ['serial.c', 'serial_ops.c'],
+    'RT_USING_CAN': ['can.c', 'can_ops.c'],
+    'RT_USING_I2C': ['i2c.c', 'i2c_ops.c']
+}
+
+for dep, files in optional_deps.items():
+    if GetDepend(dep):
+        src += files
+
+# 检查组合依赖
+if GetDepend('RT_USING_SERIAL') and GetDepend('RT_USING_DMA'):
+    src += ['serial_dma.c']
+
+group = DefineGroup('Drivers', src, depend = ['RT_USING_DEVICE'])
+Return('group')
+```
+
+### Q3: 如何支持多个工具链?
+
+```python
+from building import *
+import rtconfig
+
+src = ['common.c']
+
+# 工具链特定文件
+toolchain_files = {
+    'gcc': ['gcc_startup.S', 'gcc_specific.c'],
+    'armcc': ['keil_startup.s', 'keil_specific.c'],
+    'iccarm': ['iar_startup.s', 'iar_specific.c']
+}
+
+if rtconfig.PLATFORM in toolchain_files:
+    src += toolchain_files[rtconfig.PLATFORM]
+else:
+    print('Warning: Unknown toolchain', rtconfig.PLATFORM)
+
+# 工具链特定编译选项
+LOCAL_CFLAGS = ''
+if rtconfig.PLATFORM == 'gcc':
+    LOCAL_CFLAGS = '-Wno-unused-function'
+elif rtconfig.PLATFORM == 'armcc':
+    LOCAL_CFLAGS = '--diag_suppress=177'
+
+group = DefineGroup('MyComponent', src, depend = [''], 
+                    LOCAL_CFLAGS = LOCAL_CFLAGS)
+Return('group')
+```
+
+### Q4: 如何处理生成的代码?
+
+```python
+from building import *
+import subprocess
+
+def generate_code():
+    """生成代码"""
+    # 运行代码生成器
+    cmd = ['python', 'codegen.py', '-o', 'generated.c']
+    subprocess.check_call(cmd)
+
+# 确保生成代码
+if GetDepend('RT_USING_CODEGEN'):
+    generate_code()
+    src = ['generated.c']
+else:
+    src = ['default.c']
+
+group = DefineGroup('Generated', src, depend = [''])
+Return('group')
+```
+
+### Q5: 如何组织大型项目?
+
+```python
+# 主SConscript
+from building import *
+
+objs = []
+
+# 子模块列表
+modules = [
+    'core',
+    'drivers',
+    'network',
+    'filesystem',
+    'gui'
+]
+
+# 根据配置包含模块
+for module in modules:
+    # 检查模块是否启用
+    if GetDepend('RT_USING_' + module.upper()):
+        # 构建子模块
+        objs += SConscript(module + '/SConscript')
+
+Return('objs')
+```
+
+## 总结
+
+编写高质量的SConscript需要:
+
+1. **清晰的结构**:合理组织源文件和目录
+2. **正确的依赖**:准确声明和检查依赖关系
+3. **平台兼容**:处理不同工具链和平台的差异
+4. **性能考虑**:避免不必要的文件扫描
+5. **错误处理**:优雅处理各种异常情况
+6. **文档完善**:添加必要的注释和说明
+
+通过遵循本指南的建议和最佳实践,可以编写出易维护、可扩展的构建脚本,为RT-Thread项目的构建提供坚实的基础。

+ 643 - 0
tools/docs/构建系统使用指南.md

@@ -0,0 +1,643 @@
+# RT-Thread 构建系统使用指南
+
+## 目录
+
+1. [概述](#概述)
+2. [快速开始](#快速开始)
+3. [命令行选项详解](#命令行选项详解)
+4. [工具链配置](#工具链配置)
+5. [项目生成](#项目生成)
+6. [软件包管理](#软件包管理)
+7. [高级功能](#高级功能)
+8. [常见问题](#常见问题)
+
+## 概述
+
+RT-Thread使用基于SCons的构建系统,提供了统一的跨平台构建体验。构建系统支持:
+
+- 多种编译器和IDE(GCC、Keil、IAR、VS Code等)
+- 模块化的组件管理
+- 灵活的配置系统
+- 自动化的依赖处理
+- 软件包管理功能
+
+### 系统架构图
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│                        用户命令                              │
+│                    (scons, scons --target=xxx)              │
+└─────────────────────┬───────────────────────────────────────┘
+                      │
+┌─────────────────────▼───────────────────────────────────────┐
+│                    SConstruct                                │
+│               (BSP根目录构建脚本)                            │
+└─────────────────────┬───────────────────────────────────────┘
+                      │
+┌─────────────────────▼───────────────────────────────────────┐
+│                  building.py                                 │
+│            (核心构建引擎和函数库)                            │
+├─────────────────────┬───────────────────────────────────────┤
+│ PrepareBuilding()   │ DefineGroup()   │ DoBuilding()       │
+│ 环境初始化          │ 组件定义        │ 执行构建           │
+└─────────────────────┴─────────┬─────────────────────────────┘
+                                │
+        ┌───────────────────────┼───────────────────────┐
+        │                       │                       │
+┌───────▼────────┐    ┌────────▼────────┐    ┌────────▼────────┐
+│  SConscript    │    │   rtconfig.py   │    │   rtconfig.h   │
+│  (组件脚本)    │    │  (工具链配置)   │    │  (功能配置)    │
+└────────────────┘    └─────────────────┘    └─────────────────┘
+```
+
+## 快速开始
+
+### 基本编译流程
+
+1. **进入BSP目录**
+   ```bash
+   cd bsp/stm32/stm32f103-blue-pill
+   ```
+
+2. **配置系统**(可选)
+   ```bash
+   menuconfig        # 图形化配置
+   ```
+
+3. **编译项目**
+   ```bash
+   scons            # 默认编译
+   scons -j8        # 多线程编译
+   ```
+
+4. **生成IDE项目**
+   ```bash
+   scons --target=mdk5     # 生成Keil MDK5项目
+   scons --target=iar      # 生成IAR项目
+   scons --target=vsc      # 生成VS Code项目
+   ```
+
+### 清理和重建
+
+```bash
+scons -c                    # 清理编译产物
+scons -c --target=mdk5      # 清理MDK5项目文件
+scons --dist                # 生成分发包
+```
+
+## 命令行选项详解
+
+### 基础编译选项
+
+| 选项 | 说明 | 示例 |
+|------|------|------|
+| `-j N` | 多线程编译,N为线程数 | `scons -j8` |
+| `-c` | 清理编译产物 | `scons -c` |
+| `-s` | 静默模式,不显示命令 | `scons -s` |
+| `--verbose` | 详细输出模式 | `scons --verbose` |
+
+### 项目生成选项
+
+| 选项 | 说明 | 生成的文件 |
+|------|------|------------|
+| `--target=mdk4` | Keil MDK4项目 | project.uvproj |
+| `--target=mdk5` | Keil MDK5项目 | project.uvprojx |
+| `--target=iar` | IAR工作区 | project.eww |
+| `--target=vs2012` | Visual Studio项目 | project.vcxproj |
+| `--target=vsc` | VS Code配置 | .vscode/目录 |
+| `--target=eclipse` | Eclipse CDT项目 | .project, .cproject |
+| `--target=cmake` | CMake项目 | CMakeLists.txt |
+| `--target=makefile` | 通用Makefile | Makefile |
+
+### 配置管理选项
+
+| 选项 | 说明 | 使用场景 |
+|------|------|----------|
+| `--menuconfig` | 启动图形配置界面 | 修改功能配置 |
+| `--pyconfig` | 通过Python脚本配置 | 自动化配置 |
+| `--pyconfig-silent` | 静默Python配置 | CI/CD环境 |
+| `--genconfig` | 从rtconfig.h生成.config | 配置迁移 |
+| `--useconfig=xxx` | 使用指定配置文件 | 切换配置 |
+
+### 工具链选项
+
+| 选项 | 说明 | 示例 |
+|------|------|------|
+| `--exec-path=PATH` | 指定工具链路径 | `--exec-path=/opt/gcc-arm/bin` |
+| `--exec-prefix=PREFIX` | 指定工具链前缀 | `--exec-prefix=arm-none-eabi-` |
+| `--strict` | 严格编译模式 | 开启-Werror |
+
+### 分发和调试选项
+
+| 选项 | 说明 | 用途 |
+|------|------|------|
+| `--dist` | 生成分发包 | 项目发布 |
+| `--dist-strip` | 生成精简分发包 | 最小化项目 |
+| `--dist-ide` | 生成RT-Thread Studio项目 | Studio开发 |
+| `--cscope` | 生成cscope数据库 | 代码导航 |
+| `--clang-analyzer` | 运行Clang静态分析 | 代码质量检查 |
+
+## 工具链配置
+
+### rtconfig.py配置文件
+
+每个BSP都有一个`rtconfig.py`文件,定义了工具链配置:
+
+```python
+import os
+
+# 工具链定义
+CROSS_TOOL = 'gcc'              # 工具链类型: gcc/keil/iar
+PLATFORM   = 'armcc'            # 平台标识
+
+# 编译器路径
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+else:
+    EXEC_PATH = r'C:/Keil_v5/ARM/ARMCC/bin'
+
+# 编译器前缀(GCC工具链)
+PREFIX = 'arm-none-eabi-'
+
+# 编译器定义
+CC = PREFIX + 'gcc'
+CXX = PREFIX + 'g++'
+AS = PREFIX + 'gcc'
+AR = PREFIX + 'ar'
+LINK = PREFIX + 'gcc'
+SIZE = PREFIX + 'size'
+OBJDUMP = PREFIX + 'objdump'
+OBJCPY = PREFIX + 'objcopy'
+
+# 设备相关参数
+DEVICE = ' -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections'
+
+# 编译标志
+CFLAGS = DEVICE + ' -Dgcc'
+AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
+LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T link.lds'
+
+# 路径定义
+CPATH = ''
+LPATH = ''
+
+# 链接脚本
+LINK_SCRIPT = 'link.lds'
+
+# 后处理命令
+POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+```
+
+### 支持的工具链
+
+1. **GCC工具链**
+   ```python
+   CROSS_TOOL = 'gcc'
+   PREFIX = 'arm-none-eabi-'
+   ```
+
+2. **Keil MDK**
+   ```python
+   CROSS_TOOL = 'keil'
+   PLATFORM = 'armcc'      # ARM Compiler 5
+   # 或
+   PLATFORM = 'armclang'   # ARM Compiler 6
+   ```
+
+3. **IAR**
+   ```python
+   CROSS_TOOL = 'iar'
+   PLATFORM = 'iccarm'
+   ```
+
+4. **RISC-V GCC**
+   ```python
+   CROSS_TOOL = 'gcc'
+   PREFIX = 'riscv64-unknown-elf-'
+   ```
+
+### 环境变量支持
+
+构建系统支持通过环境变量覆盖配置:
+
+```bash
+# 设置工具链路径
+export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin
+
+# 设置工具链前缀
+export RTT_CC_PREFIX=arm-none-eabi-
+
+# 设置工具链类型
+export RTT_CC=gcc
+```
+
+## 项目生成
+
+### VS Code项目配置
+
+使用`scons --target=vsc`生成VS Code项目,会创建以下配置文件:
+
+**.vscode/c_cpp_properties.json** - IntelliSense配置
+```json
+{
+    "configurations": [
+        {
+            "name": "RT-Thread",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../../components/finsh",
+                "${workspaceFolder}/../../include"
+            ],
+            "defines": [
+                "RT_USING_FINSH",
+                "RT_USING_SERIAL",
+                "__GNUC__"
+            ],
+            "compilerPath": "/opt/gcc-arm/bin/arm-none-eabi-gcc",
+            "cStandard": "c99",
+            "cppStandard": "c++11"
+        }
+    ]
+}
+```
+
+**.vscode/tasks.json** - 构建任务配置
+```json
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build",
+            "type": "shell",
+            "command": "scons",
+            "problemMatcher": "$gcc",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        }
+    ]
+}
+```
+
+### CMake项目生成
+
+使用`scons --target=cmake`生成CMakeLists.txt:
+
+```cmake
+cmake_minimum_required(VERSION 3.10)
+
+# 工具链设置
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR cortex-m3)
+set(CMAKE_C_COMPILER arm-none-eabi-gcc)
+set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
+
+project(rtthread C ASM)
+
+# 编译选项
+add_compile_options(
+    -mcpu=cortex-m3
+    -mthumb
+    -ffunction-sections
+    -fdata-sections
+    -Wall
+    -O0
+    -g
+)
+
+# 头文件路径
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../include
+)
+
+# 源文件
+set(SOURCES
+    applications/main.c
+    ../../src/clock.c
+    ../../src/components.c
+)
+
+# 生成可执行文件
+add_executable(${PROJECT_NAME}.elf ${SOURCES})
+
+# 链接选项
+target_link_options(${PROJECT_NAME}.elf PRIVATE
+    -T${CMAKE_CURRENT_SOURCE_DIR}/link.lds
+    -Wl,-Map=${PROJECT_NAME}.map,--cref
+    -Wl,--gc-sections
+)
+```
+
+## 软件包管理
+
+### 使用package.json定义组件
+
+RT-Thread支持使用`package.json`文件定义软件包:
+
+```json
+{
+    "name": "my-driver",
+    "version": "1.0.0",
+    "type": "rt-thread-component",
+    "license": "Apache-2.0",
+    "dependencies": {
+        "RT_USING_DEVICE": "latest"
+    },
+    "sources": {
+        "common": {
+            "source_files": ["src/*.c"],
+            "header_files": ["inc/*.h"],
+            "header_path": ["inc"]
+        },
+        "cortex-m": {
+            "condition": "defined(ARCH_ARM_CORTEX_M)",
+            "source_files": ["port/cortex-m/*.c"]
+        }
+    }
+}
+```
+
+### 在SConscript中使用BuildPackage
+
+```python
+from building import *
+import os
+
+# 使用package.json构建
+objs = BuildPackage('package.json')
+
+# 或者手动指定包路径
+pkg_path = os.path.join(GetCurrentDir(), 'package.json')
+objs = BuildPackage(pkg_path)
+
+Return('objs')
+```
+
+## 高级功能
+
+### 1. 条件编译和依赖管理
+
+**基于宏定义的条件编译**
+```python
+src = ['common.c']
+
+if GetDepend('RT_USING_SERIAL'):
+    src += ['serial.c']
+
+if GetDepend(['RT_USING_SPI', 'RT_USING_SFUD']):
+    src += ['spi_flash.c']
+
+group = DefineGroup('Drivers', src, depend = ['RT_USING_DEVICE'])
+```
+
+**复杂依赖表达式**
+```python
+# 依赖可以是列表(AND关系)
+depend = ['RT_USING_LWIP', 'RT_USING_NETDEV']
+
+# 或者使用GetDepend进行复杂判断
+if GetDepend('RT_USING_LWIP') and not GetDepend('RT_USING_SAL'):
+    print('配置错误:LWIP需要SAL支持')
+```
+
+### 2. 本地编译选项
+
+为特定模块设置独立的编译选项:
+
+```python
+# 全局编译选项
+CPPPATH = [GetCurrentDir()]
+CPPDEFINES = ['MODULE_VERSION=1']
+
+# 本地编译选项(仅对当前group有效)
+LOCAL_CFLAGS = '-O3 -funroll-loops'
+LOCAL_CPPPATH = ['./private']
+LOCAL_CPPDEFINES = {'BUFFER_SIZE': 1024}
+
+group = DefineGroup('Module', src, depend = [''],
+    CPPPATH = CPPPATH,
+    CPPDEFINES = CPPDEFINES,
+    LOCAL_CFLAGS = LOCAL_CFLAGS,
+    LOCAL_CPPPATH = LOCAL_CPPPATH,
+    LOCAL_CPPDEFINES = LOCAL_CPPDEFINES
+)
+```
+
+### 3. 递归构建子目录
+
+自动扫描并构建子目录:
+
+```python
+import os
+from building import *
+
+objs = []
+cwd = GetCurrentDir()
+dirs = os.listdir(cwd)
+
+# 黑名单目录
+skip_dirs = ['test', 'doc', 'example']
+
+for d in dirs:
+    if d in skip_dirs:
+        continue
+    
+    path = os.path.join(cwd, d)
+    if os.path.isdir(path):
+        sconscript = os.path.join(path, 'SConscript')
+        if os.path.isfile(sconscript):
+            objs += SConscript(sconscript)
+
+Return('objs')
+```
+
+### 4. 自定义构建动作
+
+添加构建前后的自定义动作:
+
+```python
+from building import *
+
+def pre_build_action(target, source, env):
+    print('开始构建:', target[0])
+    # 执行预处理操作
+    
+def post_build_action(target, source, env):
+    print('构建完成:', target[0])
+    # 生成额外文件,如hex文件
+    import subprocess
+    subprocess.call(['arm-none-eabi-objcopy', '-O', 'ihex', 
+                     str(target[0]), str(target[0]) + '.hex'])
+
+# 注册构建动作
+if GetOption('target') == None:
+    rtconfig.POST_ACTION = post_build_action
+```
+
+### 5. 分发包定制
+
+创建自定义分发包:
+
+```python
+# 在BSP的SConstruct中添加
+def dist_handle(BSP_ROOT, dist_dir):
+    import shutil
+    
+    # 复制必要文件
+    src_files = ['applications', 'board', 'rtconfig.py', 'SConstruct']
+    for src in src_files:
+        src_path = os.path.join(BSP_ROOT, src)
+        dst_path = os.path.join(dist_dir, src)
+        if os.path.isdir(src_path):
+            shutil.copytree(src_path, dst_path)
+        else:
+            shutil.copy2(src_path, dst_path)
+    
+    # 创建README
+    with open(os.path.join(dist_dir, 'README.md'), 'w') as f:
+        f.write('# RT-Thread BSP 分发包\n')
+        f.write('构建时间: ' + time.strftime('%Y-%m-%d %H:%M:%S\n'))
+
+# 注册分发处理函数
+AddOption('--dist-handle',
+          dest = 'dist-handle',
+          action = 'store_true',
+          default = False,
+          help = 'Enable dist handle')
+
+if GetOption('dist-handle'):
+    dist_handle(BSP_ROOT, dist_dir)
+```
+
+### 6. 代码分析集成
+
+**Clang静态分析**
+```bash
+scons --clang-analyzer
+```
+
+**生成compile_commands.json**
+```bash
+scons --target=cmake  # CMake项目会包含compile_commands.json
+# 或使用
+scons --compile-commands
+```
+
+**生成Cscope数据库**
+```bash
+scons --cscope
+```
+
+## 常见问题
+
+### Q1: 如何添加新的源文件?
+
+在相应目录的SConscript中添加:
+```python
+src = Glob('*.c')  # 自动包含所有.c文件
+# 或
+src = ['file1.c', 'file2.c']  # 手动指定
+```
+
+### Q2: 如何排除特定文件?
+
+```python
+src = Glob('*.c')
+SrcRemove(src, ['test.c', 'debug.c'])
+```
+
+### Q3: 如何处理不同配置下的源文件?
+
+```python
+src = ['common.c']
+
+if rtconfig.PLATFORM == 'gcc':
+    src += ['gcc_specific.c']
+elif rtconfig.PLATFORM == 'armcc':
+    src += ['keil_specific.c']
+```
+
+### Q4: 如何调试构建问题?
+
+1. 使用详细输出模式:
+   ```bash
+   scons --verbose
+   ```
+
+2. 查看预处理结果:
+   ```bash
+   scons --target=mdk5 --verbose  # 查看生成的项目配置
+   ```
+
+3. 检查依赖关系:
+   ```python
+   # 在SConscript中添加调试输出
+   print('GetDepend result:', GetDepend('RT_USING_XXX'))
+   ```
+
+### Q5: 如何加快编译速度?
+
+1. 使用多线程编译:
+   ```bash
+   scons -j$(nproc)  # Linux/macOS
+   scons -j8         # Windows
+   ```
+
+2. 使用ccache(GCC):
+   ```python
+   # 在rtconfig.py中
+   CC = 'ccache ' + PREFIX + 'gcc'
+   ```
+
+3. 优化依赖关系,避免不必要的重编译
+
+### Q6: 如何处理第三方库?
+
+1. **作为源码包含**
+   ```python
+   # libraries/foo/SConscript
+   src = Glob('src/*.c')
+   CPPPATH = [GetCurrentDir() + '/include']
+   
+   group = DefineGroup('foo', src, depend = ['RT_USING_FOO'], 
+                       CPPPATH = CPPPATH)
+   ```
+
+2. **作为预编译库**
+   ```python
+   # 添加库文件
+   LIBS = ['foo']
+   LIBPATH = [GetCurrentDir() + '/lib']
+   
+   group = DefineGroup('foo', [], depend = ['RT_USING_FOO'],
+                       LIBS = LIBS, LIBPATH = LIBPATH)
+   ```
+
+### Q7: 如何自定义链接脚本?
+
+在rtconfig.py中指定:
+```python
+# GCC工具链
+LINK_SCRIPT = 'board/link.lds'
+
+# Keil MDK
+LINK_SCRIPT = 'board/link.sct'
+
+# IAR
+LINK_SCRIPT = 'board/link.icf'
+```
+
+## 最佳实践
+
+1. **模块化设计**:每个功能模块使用独立的SConscript
+2. **依赖管理**:正确设置depend参数,避免编译不需要的代码
+3. **路径处理**:使用GetCurrentDir()获取当前路径,避免硬编码
+4. **条件编译**:合理使用GetDepend进行条件判断
+5. **编译选项**:全局选项放在rtconfig.py,局部选项使用LOCAL_xxx
+6. **文档维护**:在SConscript中添加必要的注释说明
+
+## 总结
+
+RT-Thread的构建系统提供了强大而灵活的项目管理能力。通过合理使用各种构建选项和功能,可以高效地进行嵌入式软件开发。建议开发者深入理解构建系统的工作原理,以便更好地利用其功能。

+ 912 - 0
tools/docs/构建系统技术原理.md

@@ -0,0 +1,912 @@
+# RT-Thread 构建系统技术原理
+
+## 目录
+
+1. [系统架构设计](#系统架构设计)
+2. [核心模块分析](#核心模块分析)
+3. [构建流程详解](#构建流程详解)
+4. [依赖管理机制](#依赖管理机制)
+5. [工具链适配层](#工具链适配层)
+6. [项目生成器架构](#项目生成器架构)
+7. [配置系统实现](#配置系统实现)
+8. [扩展机制](#扩展机制)
+
+## 系统架构设计
+
+### 整体架构图
+
+```
+┌────────────────────────────────────────────────────────────────────┐
+│                          用户接口层                                 │
+│  ┌─────────────┐  ┌──────────────┐  ┌─────────────┐  ┌──────────┐│
+│  │ 命令行接口  │  │ menuconfig   │  │ 环境变量    │  │ 配置文件 ││
+│  │ (scons)     │  │ (Kconfig)    │  │ (RTT_xxx)   │  │ (.config)││
+│  └──────┬──────┘  └──────┬───────┘  └──────┬──────┘  └─────┬────┘│
+└─────────┼─────────────────┼──────────────────┼───────────────┼─────┘
+          │                 │                  │               │
+┌─────────▼─────────────────▼──────────────────▼───────────────▼─────┐
+│                          构建引擎层                                 │
+│  ┌─────────────────────────────────────────────────────────────┐  │
+│  │                      building.py                             │  │
+│  ├─────────────┬───────────────┬─────────────┬────────────────┤  │
+│  │ 环境准备    │ 组件收集      │ 依赖处理   │ 构建执行       │  │
+│  │ Prepare     │ DefineGroup   │ GetDepend  │ DoBuilding     │  │
+│  └─────────────┴───────────────┴─────────────┴────────────────┘  │
+└────────────────────────────────────────────────────────────────────┘
+          │                 │                  │               │
+┌─────────▼─────────────────▼──────────────────▼───────────────▼─────┐
+│                          工具支撑层                                 │
+│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐  ┌──────┐│
+│  │ utils.py │  │options.py│  │package.py│  │mkdist.py│  │预处理││
+│  │ 工具函数 │  │命令选项  │  │包管理    │  │分发打包 │  │器    ││
+│  └──────────┘  └──────────┘  └──────────┘  └─────────┘  └──────┘│
+└────────────────────────────────────────────────────────────────────┘
+          │                 │                  │               │
+┌─────────▼─────────────────▼──────────────────▼───────────────▼─────┐
+│                        目标生成器层                                 │
+│  ┌────────┐  ┌────────┐  ┌────────┐  ┌────────┐  ┌────────────┐  │
+│  │keil.py │  │iar.py  │  │gcc.py  │  │vsc.py  │  │cmake.py等  │  │
+│  └────────┘  └────────┘  └────────┘  └────────┘  └────────────┘  │
+└────────────────────────────────────────────────────────────────────┘
+```
+
+### 设计原则
+
+1. **模块化设计**:每个功能模块独立,通过明确的接口交互
+2. **可扩展性**:易于添加新的工具链支持和目标生成器
+3. **跨平台兼容**:统一的抽象层处理平台差异
+4. **配置驱动**:通过配置文件控制构建行为
+
+## 核心模块分析
+
+### 1. building.py - 构建引擎核心
+
+#### 1.1 全局变量管理
+
+```python
+BuildOptions = {}  # 存储从rtconfig.h解析的宏定义
+Projects = []      # 存储所有的组件对象
+Rtt_Root = ''      # RT-Thread根目录
+Env = None         # SCons环境对象
+```
+
+#### 1.2 PrepareBuilding 函数实现
+
+```python
+def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = []):
+    """
+    准备构建环境
+    
+    参数:
+        env: SCons环境对象
+        root_directory: RT-Thread根目录
+        has_libcpu: 是否包含libcpu
+        remove_components: 需要移除的组件列表
+    """
+    # 1. 添加命令行选项
+    AddOptions()
+    
+    # 2. 设置全局环境变量
+    global Env, Rtt_Root
+    Env = env
+    Rtt_Root = os.path.abspath(root_directory)
+    
+    # 3. 配置日志系统
+    logging.basicConfig(level=logging.INFO)
+    logger = logging.getLogger('rt-scons')
+    Env['log'] = logger
+    
+    # 4. 工具链检测和配置
+    if not utils.CmdExists(os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)):
+        # 尝试自动检测工具链
+        try:
+            envm = utils.ImportModule('env_utility')
+            exec_path = envm.GetSDKPath(rtconfig.CC)
+            if exec_path:
+                rtconfig.EXEC_PATH = exec_path
+        except:
+            pass
+    
+    # 5. 解析rtconfig.h配置
+    PreProcessor = create_preprocessor_instance()
+    with open('rtconfig.h', 'r') as f:
+        PreProcessor.process_contents(f.read())
+    BuildOptions = PreProcessor.cpp_namespace
+    
+    # 6. 处理目标平台
+    if GetOption('target'):
+        # 根据目标设置工具链
+        rtconfig.CROSS_TOOL, rtconfig.PLATFORM = tgt_dict[tgt_name]
+    
+    return objs
+```
+
+#### 1.3 DefineGroup 函数实现
+
+```python
+def DefineGroup(name, src, depend, **parameters):
+    """
+    定义一个组件组
+    
+    参数:
+        name: 组名称
+        src: 源文件列表
+        depend: 依赖条件
+        **parameters: 编译参数(CPPPATH, CPPDEFINES, LIBS等)
+    
+    返回:
+        组对象列表
+    """
+    # 1. 检查依赖条件
+    if not GetDepend(depend):
+        return []
+    
+    # 2. 处理源文件
+    if isinstance(src, list):
+        # 过滤掉被移除的文件
+        src = [s for s in src if s not in removed_src]
+    
+    # 3. 创建组对象
+    group = {}
+    group['name'] = name
+    group['src'] = src
+    
+    # 4. 处理编译参数
+    # 全局参数
+    if 'CPPPATH' in parameters:
+        group['CPPPATH'] = parameters['CPPPATH']
+    
+    # 本地参数(仅对当前组有效)
+    if 'LOCAL_CPPPATH' in parameters:
+        paths = parameters['LOCAL_CPPPATH']
+        group['LOCAL_CPPPATH'] = [os.path.abspath(p) for p in paths]
+    
+    # 5. 注册到全局项目列表
+    Projects.append(group)
+    
+    # 6. 返回SCons对象
+    if src:
+        objs = Env.Object(src)
+    else:
+        objs = []
+    
+    return objs
+```
+
+### 2. 依赖管理机制
+
+#### 2.1 GetDepend 实现
+
+```python
+def GetDepend(depend):
+    """
+    检查依赖条件是否满足
+    
+    参数:
+        depend: 字符串或字符串列表
+    
+    返回:
+        True: 依赖满足
+        False: 依赖不满足
+    """
+    # 1. 处理空依赖
+    if not depend:
+        return True
+    
+    # 2. 处理字符串依赖
+    if isinstance(depend, str):
+        return _CheckSingleDepend(depend)
+    
+    # 3. 处理列表依赖(AND关系)
+    if isinstance(depend, list):
+        for d in depend:
+            if not _CheckSingleDepend(d):
+                return False
+        return True
+    
+    return False
+
+def _CheckSingleDepend(depend):
+    """检查单个依赖"""
+    # 1. 检查是否在BuildOptions中定义
+    if depend in BuildOptions:
+        # 2. 检查值是否为真
+        return BuildOptions[depend] != '0'
+    return False
+```
+
+#### 2.2 依赖表达式支持
+
+```python
+# 支持的依赖表达式
+depend = 'RT_USING_SERIAL'           # 单个依赖
+depend = ['RT_USING_LWIP', 'SAL']    # AND关系
+depend = ''                          # 无条件包含
+
+# 高级用法 - 在SConscript中
+if GetDepend('RT_USING_LWIP'):
+    if GetDepend('RT_USING_LWIP_TCP'):
+        src += ['tcp.c']
+    if GetDepend('RT_USING_LWIP_UDP'):
+        src += ['udp.c']
+```
+
+### 3. 配置解析系统
+
+#### 3.1 预处理器实现
+
+```python
+class PreProcessor:
+    """
+    C预处理器实现,用于解析rtconfig.h
+    """
+    def __init__(self):
+        self.cpp_namespace = {}
+        self.defines = {}
+    
+    def process_contents(self, contents):
+        """处理文件内容"""
+        lines = contents.split('\n')
+        
+        for line in lines:
+            # 处理 #define 指令
+            if line.startswith('#define'):
+                self._process_define(line)
+            # 处理 #ifdef 等条件编译
+            elif line.startswith('#ifdef'):
+                self._process_ifdef(line)
+    
+    def _process_define(self, line):
+        """处理宏定义"""
+        # #define RT_NAME_MAX 8
+        parts = line.split(None, 2)
+        if len(parts) >= 2:
+            name = parts[1]
+            value = parts[2] if len(parts) > 2 else '1'
+            self.cpp_namespace[name] = value
+```
+
+#### 3.2 配置文件格式
+
+**rtconfig.h 示例**
+```c
+/* RT-Thread 配置文件 */
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* 内核配置 */
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_USING_TIMER_SOFT
+
+/* 组件配置 */
+#define RT_USING_DEVICE
+#define RT_USING_SERIAL
+#define RT_SERIAL_RB_BUFSZ 64
+
+/* 条件配置 */
+#ifdef RT_USING_SERIAL
+    #define RT_SERIAL_USING_DMA
+#endif
+
+#endif /* RT_CONFIG_H__ */
+```
+
+### 4. 工具链适配层
+
+#### 4.1 工具链抽象接口
+
+```python
+class ToolchainBase:
+    """工具链基类"""
+    def __init__(self):
+        self.name = ''
+        self.prefix = ''
+        self.suffix = ''
+    
+    def get_cc(self):
+        """获取C编译器"""
+        raise NotImplementedError
+    
+    def get_cflags(self):
+        """获取C编译选项"""
+        raise NotImplementedError
+    
+    def get_linkflags(self):
+        """获取链接选项"""
+        raise NotImplementedError
+```
+
+#### 4.2 GCC工具链实现
+
+```python
+class GccToolchain(ToolchainBase):
+    def __init__(self, prefix=''):
+        self.name = 'gcc'
+        self.prefix = prefix
+        self.suffix = ''
+    
+    def get_cc(self):
+        return self.prefix + 'gcc'
+    
+    def get_cflags(self):
+        flags = []
+        # 基础选项
+        flags += ['-Wall', '-g']
+        # 优化选项
+        if GetOption('optimization') == 'size':
+            flags += ['-Os']
+        else:
+            flags += ['-O0']
+        # 架构选项
+        flags += ['-mcpu=cortex-m3', '-mthumb']
+        return ' '.join(flags)
+```
+
+#### 4.3 Keil MDK适配
+
+```python
+class KeilToolchain(ToolchainBase):
+    def __init__(self):
+        self.name = 'keil'
+        
+    def setup_environment(self, env):
+        """设置Keil特定的环境变量"""
+        # 修改文件扩展名
+        env['OBJSUFFIX'] = '.o'
+        env['LIBPREFIX'] = ''
+        env['LIBSUFFIX'] = '.lib'
+        
+        # 设置编译命令
+        env['CC'] = 'armcc'
+        env['AS'] = 'armasm'
+        env['AR'] = 'armar'
+        env['LINK'] = 'armlink'
+        
+        # 设置命令格式
+        env['ARCOM'] = '$AR --create $TARGET $SOURCES'
+```
+
+### 5. 项目生成器架构
+
+#### 5.1 生成器基类
+
+```python
+class ProjectGenerator:
+    """项目生成器基类"""
+    def __init__(self, env, project):
+        self.env = env
+        self.project = project
+        self.template_dir = ''
+    
+    def generate(self):
+        """生成项目文件"""
+        self._prepare()
+        self._generate_project_file()
+        self._generate_workspace_file()
+        self._copy_template_files()
+        self._post_process()
+    
+    def _collect_source_files(self):
+        """收集源文件"""
+        sources = []
+        for group in self.project:
+            sources.extend(group['src'])
+        return sources
+    
+    def _collect_include_paths(self):
+        """收集头文件路径"""
+        paths = []
+        for group in self.project:
+            if 'CPPPATH' in group:
+                paths.extend(group['CPPPATH'])
+        return list(set(paths))  # 去重
+```
+
+#### 5.2 VS Code生成器实现
+
+```python
+class VSCodeGenerator(ProjectGenerator):
+    """VS Code项目生成器"""
+    
+    def _generate_project_file(self):
+        """生成VS Code配置文件"""
+        # 创建.vscode目录
+        vscode_dir = os.path.join(self.env['BSP_ROOT'], '.vscode')
+        if not os.path.exists(vscode_dir):
+            os.makedirs(vscode_dir)
+        
+        # 生成c_cpp_properties.json
+        self._generate_cpp_properties()
+        
+        # 生成tasks.json
+        self._generate_tasks()
+        
+        # 生成launch.json
+        self._generate_launch()
+    
+    def _generate_cpp_properties(self):
+        """生成IntelliSense配置"""
+        config = {
+            "configurations": [{
+                "name": "RT-Thread",
+                "includePath": self._collect_include_paths(),
+                "defines": self._collect_defines(),
+                "compilerPath": self._get_compiler_path(),
+                "cStandard": "c99",
+                "cppStandard": "c++11",
+                "intelliSenseMode": "gcc-arm"
+            }],
+            "version": 4
+        }
+        
+        # 写入文件
+        file_path = os.path.join('.vscode', 'c_cpp_properties.json')
+        with open(file_path, 'w') as f:
+            json.dump(config, f, indent=4)
+```
+
+#### 5.3 Keil MDK5生成器
+
+```python
+class MDK5Generator(ProjectGenerator):
+    """Keil MDK5项目生成器"""
+    
+    def _generate_project_file(self):
+        """生成uvprojx文件"""
+        # 加载XML模板
+        tree = etree.parse(self.template_file)
+        root = tree.getroot()
+        
+        # 更新目标配置
+        self._update_target_options(root)
+        
+        # 添加文件组
+        groups_node = root.find('.//Groups')
+        for group in self.project:
+            self._add_file_group(groups_node, group)
+        
+        # 保存项目文件
+        tree.write('project.uvprojx', encoding='utf-8', 
+                   xml_declaration=True)
+    
+    def _add_file_group(self, parent, group):
+        """添加文件组"""
+        group_elem = etree.SubElement(parent, 'Group')
+        
+        # 组名
+        name_elem = etree.SubElement(group_elem, 'GroupName')
+        name_elem.text = group['name']
+        
+        # 文件列表
+        files_elem = etree.SubElement(group_elem, 'Files')
+        for src in group['src']:
+            self._add_file(files_elem, src)
+```
+
+### 6. 编译数据库生成
+
+#### 6.1 compile_commands.json生成
+
+```python
+def generate_compile_commands(env, project):
+    """
+    生成compile_commands.json用于代码分析工具
+    """
+    commands = []
+    
+    for group in project:
+        for src in group['src']:
+            if src.endswith('.c') or src.endswith('.cpp'):
+                cmd = {
+                    "directory": env['BSP_ROOT'],
+                    "file": os.path.abspath(src),
+                    "command": _generate_compile_command(env, src, group)
+                }
+                commands.append(cmd)
+    
+    # 写入文件
+    with open('compile_commands.json', 'w') as f:
+        json.dump(commands, f, indent=2)
+
+def _generate_compile_command(env, src, group):
+    """生成单个文件的编译命令"""
+    cmd = []
+    
+    # 编译器
+    cmd.append(env['CC'])
+    
+    # 编译选项
+    cmd.extend(env['CFLAGS'].split())
+    
+    # 头文件路径
+    for path in group.get('CPPPATH', []):
+        cmd.append('-I' + path)
+    
+    # 宏定义
+    for define in group.get('CPPDEFINES', []):
+        if isinstance(define, tuple):
+            cmd.append('-D{}={}'.format(define[0], define[1]))
+        else:
+            cmd.append('-D' + define)
+    
+    # 源文件
+    cmd.append(src)
+    
+    return ' '.join(cmd)
+```
+
+### 7. 分发系统实现
+
+#### 7.1 分发包生成流程
+
+```python
+def MkDist(program, BSP_ROOT, RTT_ROOT, Env, project):
+    """生成分发包"""
+    # 1. 创建分发目录
+    dist_name = os.path.basename(BSP_ROOT)
+    dist_dir = os.path.join(BSP_ROOT, 'dist', dist_name)
+    
+    # 2. 复制RT-Thread内核
+    print('=> copy RT-Thread kernel')
+    copytree(os.path.join(RTT_ROOT, 'src'), 
+             os.path.join(dist_dir, 'rt-thread', 'src'))
+    copytree(os.path.join(RTT_ROOT, 'include'),
+             os.path.join(dist_dir, 'rt-thread', 'include'))
+    
+    # 3. 复制使用的组件
+    print('=> copy components')
+    for group in project:
+        _copy_group_files(group, dist_dir)
+    
+    # 4. 生成Kconfig文件
+    _generate_kconfig(dist_dir, project)
+    
+    # 5. 打包
+    make_zip(dist_dir, dist_name + '.zip')
+```
+
+#### 7.2 精简分发包生成
+
+```python
+def MkDist_Strip(program, BSP_ROOT, RTT_ROOT, Env):
+    """
+    基于compile_commands.json生成精简分发包
+    只包含实际使用的文件
+    """
+    # 1. 解析compile_commands.json
+    with open('compile_commands.json', 'r') as f:
+        commands = json.load(f)
+    
+    # 2. 提取使用的文件
+    used_files = set()
+    for cmd in commands:
+        # 源文件
+        used_files.add(cmd['file'])
+        
+        # 解析包含的头文件
+        includes = _parse_includes(cmd['file'], cmd['command'])
+        used_files.update(includes)
+    
+    # 3. 复制文件
+    for file in used_files:
+        _copy_with_structure(file, dist_dir)
+```
+
+## 构建流程详解
+
+### 完整构建流程图
+
+```
+┌──────────────┐
+│  用户输入    │
+│   scons      │
+└──────┬───────┘
+       │
+┌──────▼───────┐
+│  SConstruct  │ ← 读取rtconfig.py
+│   主脚本     │ ← 调用PrepareBuilding
+└──────┬───────┘
+       │
+┌──────▼───────┐
+│ 环境初始化   │
+│ ·设置路径    │
+│ ·检测工具链  │
+│ ·解析配置    │
+└──────┬───────┘
+       │
+┌──────▼───────┐
+│ 递归处理     │
+│ SConscript   │ ← 调用DefineGroup
+│ ·收集源文件  │ ← 检查依赖GetDepend
+│ ·设置参数    │
+└──────┬───────┘
+       │
+┌──────▼───────┐
+│ 构建执行     │
+│ DoBuilding   │
+│ ·合并对象    │
+│ ·链接程序    │
+└──────┬───────┘
+       │
+┌──────▼───────┐
+│ 后处理       │
+│ ·生成bin文件 │
+│ ·显示大小    │
+│ ·自定义动作  │
+└──────────────┘
+```
+
+### 依赖解析流程
+
+```python
+def dependency_resolution_flow():
+    """
+    依赖解析流程示例
+    """
+    # 1. 从rtconfig.h读取所有宏定义
+    macros = parse_rtconfig_h()
+    # 例: {'RT_USING_SERIAL': '1', 'RT_USING_PIN': '1'}
+    
+    # 2. 处理单个组件
+    for component in components:
+        # 3. 检查依赖条件
+        if check_dependencies(component.depends, macros):
+            # 4. 包含组件
+            include_component(component)
+        else:
+            # 5. 跳过组件
+            skip_component(component)
+    
+    # 6. 递归处理子依赖
+    resolve_sub_dependencies()
+```
+
+## 扩展机制
+
+### 1. 添加新的工具链支持
+
+```python
+# 1. 在tgt_dict中添加映射
+tgt_dict['mycc'] = ('mycc', 'mycc')
+
+# 2. 创建tools/mycc.py
+import os
+from building import *
+
+def generate_project(env, project):
+    """生成项目文件"""
+    print("Generating MyCC project...")
+    
+    # 收集信息
+    info = ProjectInfo(env, project)
+    
+    # 生成项目文件
+    # ...
+
+# 3. 在rtconfig.py中配置
+CROSS_TOOL = 'mycc'
+PLATFORM = 'mycc'
+```
+
+### 2. 添加自定义构建步骤
+
+```python
+# 在SConstruct或SConscript中
+def custom_builder(target, source, env):
+    """自定义构建器"""
+    # 执行自定义操作
+    cmd = 'custom_tool -o {} {}'.format(target[0], source[0])
+    os.system(cmd)
+
+# 注册构建器
+env['BUILDERS']['CustomBuild'] = Builder(action=custom_builder,
+                                         suffix='.out',
+                                         src_suffix='.in')
+
+# 使用构建器
+custom_out = env.CustomBuild('output.out', 'input.in')
+```
+
+### 3. 扩展配置解析器
+
+```python
+class ExtendedPreProcessor(PreProcessor):
+    """扩展的预处理器"""
+    
+    def __init__(self):
+        super().__init__()
+        self.custom_handlers = {}
+    
+    def register_handler(self, directive, handler):
+        """注册自定义指令处理器"""
+        self.custom_handlers[directive] = handler
+    
+    def process_line(self, line):
+        """处理单行"""
+        # 检查自定义指令
+        for directive, handler in self.custom_handlers.items():
+            if line.startswith(directive):
+                return handler(line)
+        
+        # 默认处理
+        return super().process_line(line)
+```
+
+### 4. 插件系统实现
+
+```python
+class BuildPlugin:
+    """构建插件基类"""
+    
+    def __init__(self, name):
+        self.name = name
+    
+    def pre_build(self, env, project):
+        """构建前钩子"""
+        pass
+    
+    def post_build(self, env, project):
+        """构建后钩子"""
+        pass
+    
+    def configure(self, env):
+        """配置环境"""
+        pass
+
+# 插件管理器
+class PluginManager:
+    def __init__(self):
+        self.plugins = []
+    
+    def register(self, plugin):
+        self.plugins.append(plugin)
+    
+    def run_pre_build(self, env, project):
+        for plugin in self.plugins:
+            plugin.pre_build(env, project)
+```
+
+## 性能优化
+
+### 1. 构建缓存机制
+
+```python
+class BuildCache:
+    """构建缓存"""
+    
+    def __init__(self, cache_dir='.scache'):
+        self.cache_dir = cache_dir
+        self.cache_db = os.path.join(cache_dir, 'cache.db')
+    
+    def get_hash(self, file):
+        """计算文件哈希"""
+        import hashlib
+        with open(file, 'rb') as f:
+            return hashlib.md5(f.read()).hexdigest()
+    
+    def is_cached(self, source, target):
+        """检查是否已缓存"""
+        # 检查目标文件是否存在
+        if not os.path.exists(target):
+            return False
+        
+        # 检查源文件是否更新
+        source_hash = self.get_hash(source)
+        cached_hash = self.load_hash(source)
+        
+        return source_hash == cached_hash
+```
+
+### 2. 并行构建优化
+
+```python
+def optimize_parallel_build(env, project):
+    """优化并行构建"""
+    # 1. 分析依赖关系
+    dep_graph = analyze_dependencies(project)
+    
+    # 2. 计算最优构建顺序
+    build_order = topological_sort(dep_graph)
+    
+    # 3. 分组独立任务
+    parallel_groups = []
+    for level in build_order:
+        # 同一层级可以并行
+        parallel_groups.append(level)
+    
+    # 4. 设置并行度
+    import multiprocessing
+    num_jobs = multiprocessing.cpu_count()
+    env.SetOption('num_jobs', num_jobs)
+    
+    return parallel_groups
+```
+
+## 调试技巧
+
+### 1. 构建日志分析
+
+```python
+# 启用详细日志
+def enable_build_logging():
+    # 设置SCons日志
+    env.SetOption('debug', 'explain')
+    
+    # 自定义日志
+    class BuildLogger:
+        def __init__(self, logfile):
+            self.logfile = logfile
+        
+        def __call__(self, msg, *args):
+            with open(self.logfile, 'a') as f:
+                f.write(msg % args + '\n')
+    
+    logger = BuildLogger('build.log')
+    env['PRINT_CMD_LINE_FUNC'] = logger
+```
+
+### 2. 依赖关系可视化
+
+```python
+def visualize_dependencies(project):
+    """生成依赖关系图"""
+    import graphviz
+    
+    dot = graphviz.Digraph(comment='Dependencies')
+    
+    # 添加节点
+    for group in project:
+        dot.node(group['name'])
+    
+    # 添加边
+    for group in project:
+        for dep in group.get('depends', []):
+            if find_group(dep):
+                dot.edge(dep, group['name'])
+    
+    # 渲染
+    dot.render('dependencies', format='png')
+```
+
+## 最佳实践
+
+### 1. 模块化设计原则
+
+- 每个功能模块独立的SConscript
+- 明确的依赖关系声明
+- 避免循环依赖
+- 使用统一的命名规范
+
+### 2. 性能优化建议
+
+- 使用Glob谨慎,大目录下性能差
+- 合理设置并行编译数
+- 使用增量编译
+- 避免重复的文件扫描
+
+### 3. 可维护性建议
+
+- 添加充分的注释
+- 使用有意义的变量名
+- 遵循Python PEP8规范
+- 定期清理无用代码
+
+### 4. 跨平台兼容性
+
+- 使用os.path处理路径
+- 避免平台特定的命令
+- 测试多平台构建
+- 处理路径分隔符差异
+
+## 总结
+
+RT-Thread的构建系统是一个精心设计的模块化系统,通过清晰的架构和灵活的扩展机制,为嵌入式开发提供了强大的构建能力。理解其内部原理有助于:
+
+1. 更好地使用和优化构建流程
+2. 快速定位和解决构建问题
+3. 扩展支持新的工具链和平台
+4. 为项目定制构建流程
+
+构建系统的核心价值在于将复杂的嵌入式构建过程标准化和自动化,让开发者能够专注于功能开发而不是构建配置。

+ 345 - 0
tools/ng/README.md

@@ -0,0 +1,345 @@
+# RT-Thread Next Generation Build System
+
+## 概述
+
+RT-Thread NG(Next Generation)构建系统是对现有构建系统的面向对象重构,在保持完全向后兼容的同时,提供了更清晰的架构和更强的可扩展性。
+
+## 特性
+
+- ✅ **完全向后兼容**:现有的SConscript无需修改
+- ✅ **面向对象设计**:清晰的类层次结构和职责分离
+- ✅ **SCons最佳实践**:充分利用SCons的Environment对象
+- ✅ **可扩展架构**:易于添加新的工具链和项目生成器
+- ✅ **类型安全**:更好的类型提示和错误处理
+
+## 架构设计
+
+### 核心模块
+
+```
+ng/
+├── __init__.py          # 包初始化
+├── core.py              # 核心类:BuildContext
+├── environment.py       # 环境扩展:RTEnv类,注入到SCons Environment
+├── config.py            # 配置管理:解析rtconfig.h
+├── project.py           # 项目管理:ProjectGroup和Registry
+├── toolchain.py         # 工具链抽象:GCC、Keil、IAR等
+├── generator.py         # 项目生成器:VS Code、CMake等
+├── utils.py             # 工具函数:路径、版本等
+├── adapter.py           # 适配器:与building.py集成
+└── building_ng.py       # 示例:最小化修改的building.py
+```
+
+### 类图
+
+```mermaid
+classDiagram
+    class BuildContext {
+        +root_directory: str
+        +config_manager: ConfigManager
+        +project_registry: ProjectRegistry
+        +toolchain_manager: ToolchainManager
+        +prepare_environment(env)
+        +get_dependency(depend): bool
+    }
+    
+    class ConfigManager {
+        +load_from_file(filepath)
+        +get_dependency(depend): bool
+        +get_option(name): ConfigOption
+    }
+    
+    class ProjectGroup {
+        +name: str
+        +sources: List[str]
+        +dependencies: List[str]
+        +build(env): List[Object]
+    }
+    
+    class Toolchain {
+        <<abstract>>
+        +get_name(): str
+        +detect(): bool
+        +configure_environment(env)
+    }
+    
+    class ProjectGenerator {
+        <<abstract>>
+        +generate(context, info): bool
+        +clean(): bool
+    }
+    
+    BuildContext --> ConfigManager
+    BuildContext --> ProjectRegistry
+    BuildContext --> ToolchainManager
+    ProjectRegistry --> ProjectGroup
+    ToolchainManager --> Toolchain
+```
+
+## 使用方法
+
+### 1. 最小化集成(推荐)
+
+在building.py中添加少量代码即可集成新系统:
+
+```python
+# 在building.py的开头添加
+try:
+    from ng.adapter import (
+        init_build_context,
+        inject_environment_methods,
+        load_rtconfig as ng_load_rtconfig
+    )
+    USE_NG = True
+except ImportError:
+    USE_NG = False
+
+# 在PrepareBuilding函数中添加
+def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components=[]):
+    # ... 原有代码 ...
+    
+    # 集成新系统
+    if USE_NG:
+        context = init_build_context(root_directory)
+        inject_environment_methods(env)
+        ng_load_rtconfig('rtconfig.h')
+    
+    # ... 继续原有代码 ...
+```
+
+### 2. 使用新的环境方法
+
+集成后,SCons Environment对象会自动获得新方法:
+
+```python
+# 在SConscript中使用新方法
+Import('env')
+
+# 使用环境方法(推荐)
+src = env.GlobFiles('*.c')
+group = env.DefineGroup('MyComponent', src, depend=['RT_USING_XXX'])
+
+# 也可以使用传统方式(保持兼容)
+from building import *
+group = DefineGroup('MyComponent', src, depend=['RT_USING_XXX'])
+```
+
+### 3. 新的项目生成器
+
+新系统提供了改进的项目生成器:
+
+```bash
+# 生成VS Code项目
+scons --target=vscode
+
+# 生成CMake项目
+scons --target=cmake
+```
+
+## API参考
+
+### 环境方法
+
+所有方法都被注入到SCons Environment对象中:
+
+#### env.DefineGroup(name, src, depend, **kwargs)
+定义一个组件组。
+
+**参数:**
+- `name`: 组名称
+- `src`: 源文件列表
+- `depend`: 依赖条件(字符串或列表)
+- `**kwargs`: 额外参数
+  - `CPPPATH`: 头文件路径
+  - `CPPDEFINES`: 宏定义
+  - `CFLAGS`/`CXXFLAGS`: 编译选项
+  - `LOCAL_CFLAGS`/`LOCAL_CPPPATH`: 仅对当前组有效的选项
+  - `LIBS`/`LIBPATH`: 库配置
+
+**返回:** 构建对象列表
+
+**示例:**
+```python
+src = ['driver.c', 'hal.c']
+group = env.DefineGroup('Driver', 
+    src, 
+    depend=['RT_USING_DEVICE'],
+    CPPPATH=[env.GetCurrentDir()],
+    LOCAL_CFLAGS='-O3'
+)
+```
+
+#### env.GetDepend(depend)
+检查依赖是否满足。
+
+**参数:**
+- `depend`: 依赖名称或列表
+
+**返回:** True如果依赖满足
+
+**示例:**
+```python
+if env.GetDepend('RT_USING_SERIAL'):
+    src += ['serial.c']
+
+if env.GetDepend(['RT_USING_SERIAL', 'RT_SERIAL_USING_DMA']):
+    src += ['serial_dma.c']
+```
+
+#### env.SrcRemove(src, remove)
+从源文件列表中移除文件。
+
+**参数:**
+- `src`: 源文件列表(就地修改)
+- `remove`: 要移除的文件
+
+**示例:**
+```python
+src = env.GlobFiles('*.c')
+env.SrcRemove(src, ['test.c', 'debug.c'])
+```
+
+#### env.BuildPackage(package_path)
+从package.json构建软件包。
+
+**参数:**
+- `package_path`: package.json路径
+
+**返回:** 构建对象列表
+
+**示例:**
+```python
+objs = env.BuildPackage('package.json')
+```
+
+#### env.GetContext()
+获取当前构建上下文。
+
+**返回:** BuildContext实例
+
+**示例:**
+```python
+context = env.GetContext()
+if context:
+    context.logger.info("Building component...")
+```
+
+## 高级特性
+
+### 1. 自定义工具链
+
+创建自定义工具链:
+
+```python
+from ng.toolchain import Toolchain
+
+class MyToolchain(Toolchain):
+    def get_name(self):
+        return "mycc"
+        
+    def detect(self):
+        # 检测工具链
+        return shutil.which("mycc") is not None
+        
+    def configure_environment(self, env):
+        env['CC'] = 'mycc'
+        env['CFLAGS'] = '-O2 -Wall'
+        
+# 注册工具链
+context = env.GetContext()
+context.toolchain_manager.register_toolchain('mycc', MyToolchain())
+```
+
+### 2. 自定义项目生成器
+
+创建自定义项目生成器:
+
+```python
+from ng.generator import ProjectGenerator
+
+class MyGenerator(ProjectGenerator):
+    def get_name(self):
+        return "myide"
+        
+    def generate(self, context, project_info):
+        # 生成项目文件
+        self._ensure_output_dir()
+        # ... 生成逻辑 ...
+        return True
+        
+# 注册生成器
+context.generator_registry.register('myide', MyGenerator)
+```
+
+### 3. 构建钩子
+
+使用构建上下文添加钩子:
+
+```python
+context = env.GetContext()
+
+# 添加日志
+context.logger.info("Starting build...")
+
+# 访问配置
+if context.config_manager.get_option('RT_THREAD_PRIORITY_MAX'):
+    print("Max priority:", context.config_manager.get_value('RT_THREAD_PRIORITY_MAX'))
+
+# 获取项目信息
+info = context.project_registry.get_project_info()
+print(f"Total sources: {len(info['all_sources'])}")
+```
+
+## 迁移指南
+
+### 从旧版本迁移
+
+1. **无需修改**:现有的SConscript文件无需任何修改即可工作
+2. **可选升级**:可以逐步将`DefineGroup`调用改为`env.DefineGroup`
+3. **新功能**:可以开始使用新的特性如`env.BuildPackage`
+
+### 最佳实践
+
+1. **使用环境方法**:优先使用`env.DefineGroup`而不是全局函数
+2. **类型提示**:在Python 3.5+中使用类型提示
+3. **错误处理**:使用context.logger记录错误和警告
+4. **路径处理**:使用PathService处理跨平台路径
+
+## 性能优化
+
+新系统包含多项性能优化:
+
+1. **配置缓存**:依赖检查结果会被缓存
+2. **延迟加载**:工具链和生成器按需加载
+3. **并行支持**:项目生成可以并行执行
+
+## 测试
+
+运行测试套件:
+
+```bash
+cd tools/ng
+python -m pytest tests/
+```
+
+## 贡献
+
+欢迎贡献代码!请遵循以下准则:
+
+1. 保持向后兼容性
+2. 添加类型提示
+3. 编写单元测试
+4. 更新文档
+
+## 路线图
+
+- [ ] 完整的测试覆盖
+- [ ] 性能基准测试
+- [ ] 插件系统
+- [ ] 更多项目生成器(Eclipse、Qt Creator等)
+- [ ] 构建缓存系统
+- [ ] 分布式构建支持
+
+## 许可证
+
+本项目遵循RT-Thread的Apache License 2.0许可证。

+ 25 - 0
tools/ng/__init__.py

@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+"""
+RT-Thread Next Generation Build System
+
+This module provides an object-oriented implementation of the RT-Thread build system
+while maintaining backward compatibility with the existing building.py interface.
+"""
+
+from .core import BuildContext
+from .environment import RTEnv
+from .config import ConfigManager
+from .project import ProjectRegistry, ProjectGroup
+from .toolchain import ToolchainManager
+from .generator import GeneratorRegistry
+
+__version__ = "1.0.0"
+__all__ = [
+    'BuildContext',
+    'RTEnv', 
+    'ConfigManager',
+    'ProjectRegistry',
+    'ProjectGroup',
+    'ToolchainManager',
+    'GeneratorRegistry'
+]

+ 218 - 0
tools/ng/adapter.py

@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+"""
+Adapter module to integrate new OOP implementation with existing building.py.
+
+This module provides the bridge between the legacy function-based API and the new
+object-oriented implementation, ensuring backward compatibility.
+"""
+
+import os
+from typing import List, Dict, Any, Optional
+
+from .core import BuildContext
+from .environment import RTEnv
+from .generator import GeneratorConfig, GeneratorRegistry
+
+
+# Global variables for compatibility
+_context: Optional[BuildContext] = None
+
+
+def init_build_context(root_directory: str) -> BuildContext:
+    """
+    Initialize the build context.
+    
+    This function should be called early in PrepareBuilding.
+    
+    Args:
+        root_directory: RT-Thread root directory
+        
+    Returns:
+        BuildContext instance
+    """
+    global _context
+    _context = BuildContext(root_directory)
+    return _context
+
+
+def get_build_context() -> Optional[BuildContext]:
+    """Get the current build context."""
+    return _context
+
+
+def inject_environment_methods(env) -> None:
+    """
+    Inject RT-Thread methods into SCons Environment.
+    
+    This should be called in PrepareBuilding after environment setup.
+    
+    Args:
+        env: SCons Environment object
+    """
+    RTEnv.inject_methods(env)
+    
+    # Also set the environment in context
+    if _context:
+        _context.prepare_environment(env)
+
+
+def load_rtconfig(config_file: str = 'rtconfig.h') -> Dict[str, Any]:
+    """
+    Load configuration from rtconfig.h.
+    
+    Args:
+        config_file: Configuration file name
+        
+    Returns:
+        Dictionary of build options
+    """
+    if _context:
+        _context.load_configuration(config_file)
+        return _context.build_options
+    return {}
+
+
+def DefineGroup(name: str, src: List[str], depend: Any = None, **kwargs) -> List:
+    """
+    Legacy DefineGroup function for backward compatibility.
+    
+    This function delegates to the environment method.
+    
+    Args:
+        name: Group name
+        src: Source files
+        depend: Dependencies
+        **kwargs: Additional parameters
+        
+    Returns:
+        List of build objects
+    """
+    if _context and _context.environment:
+        return _context.environment.DefineGroup(name, src, depend, **kwargs)
+    else:
+        # Fallback behavior
+        print(f"Warning: DefineGroup called before environment setup for group '{name}'")
+        return []
+
+
+def GetDepend(depend: Any) -> bool:
+    """
+    Legacy GetDepend function for backward compatibility.
+    
+    Args:
+        depend: Dependency to check
+        
+    Returns:
+        True if dependency is satisfied
+    """
+    if _context:
+        return _context.get_dependency(depend)
+    return False
+
+
+def GetCurrentDir() -> str:
+    """
+    Get current directory.
+    
+    Returns:
+        Current directory path
+    """
+    return os.path.abspath('.')
+
+
+def SrcRemove(src: List[str], remove: List[str]) -> None:
+    """
+    Remove files from source list.
+    
+    Args:
+        src: Source list (modified in place)
+        remove: Files to remove
+    """
+    if not isinstance(remove, list):
+        remove = [remove]
+        
+    for item in remove:
+        if item in src:
+            src.remove(item)
+
+
+def GetBuildOptions() -> Dict[str, Any]:
+    """
+    Get build options.
+    
+    Returns:
+        Dictionary of build options
+    """
+    if _context:
+        return _context.build_options
+    return {}
+
+
+def MergeGroups() -> List:
+    """
+    Merge all registered groups.
+    
+    Returns:
+        List of all build objects
+    """
+    if _context:
+        return _context.merge_groups()
+    return []
+
+
+def GenerateProject(target: str, env, projects: List) -> None:
+    """
+    Generate IDE project files.
+    
+    Args:
+        target: Target type (mdk5, iar, vscode, etc.)
+        env: SCons Environment
+        projects: Project list
+    """
+    if not _context:
+        print("Error: Build context not initialized")
+        return
+        
+    # Get project info from registry
+    project_info = _context.project_registry.get_project_info()
+    
+    # Create generator config
+    config = GeneratorConfig(
+        output_dir=os.getcwd(),
+        project_name=os.path.basename(os.getcwd()),
+        target_name="rtthread.elf"
+    )
+    
+    # Create and run generator
+    try:
+        generator = _context.generator_registry.create_generator(target, config)
+        if generator.generate(_context, project_info):
+            print(f"Successfully generated {target} project files")
+        else:
+            print(f"Failed to generate {target} project files")
+    except Exception as e:
+        print(f"Error generating {target} project: {e}")
+
+
+def PrepareModuleBuilding(env, root_directory, bsp_directory) -> None:
+    """
+    Prepare for building a module.
+    
+    This is a simplified version of PrepareBuilding for module compilation.
+    
+    Args:
+        env: SCons Environment
+        root_directory: RT-Thread root directory
+        bsp_directory: BSP directory
+    """
+    # Initialize context
+    context = init_build_context(root_directory)
+    context.bsp_directory = bsp_directory
+    
+    # Inject methods
+    inject_environment_methods(env)
+    
+    # Load configuration
+    config_path = os.path.join(bsp_directory, 'rtconfig.h')
+    if os.path.exists(config_path):
+        load_rtconfig(config_path)

+ 115 - 0
tools/ng/building_ng.py

@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+"""
+Next Generation building.py with minimal modifications.
+
+This file shows how to integrate the new OOP system with minimal changes to building.py.
+The actual implementation would modify the original building.py file.
+"""
+
+# Import everything from original building.py
+import sys
+import os
+
+# Add parent directory to path to import original building
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from building import *
+
+# Import new OOP modules
+from ng.adapter import (
+    init_build_context,
+    inject_environment_methods,
+    load_rtconfig as ng_load_rtconfig,
+    GenerateProject as ng_GenerateProject
+)
+
+
+# Override PrepareBuilding to integrate new system
+_original_PrepareBuilding = PrepareBuilding
+
+def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components=[]):
+    """
+    Enhanced PrepareBuilding that integrates the new OOP system.
+    
+    This function wraps the original PrepareBuilding and adds OOP functionality.
+    """
+    # Initialize new build context
+    context = init_build_context(root_directory)
+    
+    # Call original PrepareBuilding
+    result = _original_PrepareBuilding(env, root_directory, has_libcpu, remove_components)
+    
+    # Inject new methods into environment
+    inject_environment_methods(env)
+    
+    # Load configuration into new system
+    ng_load_rtconfig('rtconfig.h')
+    
+    # Store context in environment for access
+    env['_BuildContext'] = context
+    
+    return result
+
+
+# Override DefineGroup to use new implementation
+_original_DefineGroup = DefineGroup
+
+def DefineGroup(name, src, depend, **parameters):
+    """
+    Enhanced DefineGroup that uses the new OOP implementation.
+    
+    This maintains backward compatibility while using the new system internally.
+    """
+    # Get environment from global Env
+    global Env
+    if Env and hasattr(Env, 'DefineGroup'):
+        # Use new method if available
+        return Env.DefineGroup(name, src, depend, **parameters)
+    else:
+        # Fallback to original
+        return _original_DefineGroup(name, src, depend, **parameters)
+
+
+# Override GetDepend to use new implementation
+_original_GetDepend = GetDepend
+
+def GetDepend(depend):
+    """
+    Enhanced GetDepend that uses the new OOP implementation.
+    """
+    global Env
+    if Env and hasattr(Env, 'GetDepend'):
+        # Use new method if available
+        return Env.GetDepend(depend)
+    else:
+        # Fallback to original
+        return _original_GetDepend(depend)
+
+
+# Override DoBuilding to integrate project generation
+_original_DoBuilding = DoBuilding
+
+def DoBuilding(target, objects):
+    """
+    Enhanced DoBuilding that integrates new project generation.
+    """
+    # Call original DoBuilding
+    _original_DoBuilding(target, objects)
+    
+    # Handle project generation with new system
+    if GetOption('target'):
+        target_name = GetOption('target')
+        global Env, Projects
+        
+        # Use new generator if available
+        try:
+            ng_GenerateProject(target_name, Env, Projects)
+        except Exception as e:
+            print(f"Falling back to original generator: {e}")
+            # Call original GenTargetProject
+            from building import GenTargetProject
+            GenTargetProject(Projects, program=target)
+
+
+# Export enhanced functions
+__all__ = ['PrepareBuilding', 'DefineGroup', 'GetDepend', 'DoBuilding'] + \
+          [name for name in dir(sys.modules['building']) if not name.startswith('_')]

+ 297 - 0
tools/ng/config.py

@@ -0,0 +1,297 @@
+# -*- coding: utf-8 -*-
+"""
+Configuration management for RT-Thread build system.
+
+This module handles parsing and managing configuration from rtconfig.h files.
+"""
+
+import re
+import os
+from typing import Dict, List, Any, Optional, Union
+from dataclasses import dataclass
+from enum import Enum
+
+
+class ConfigType(Enum):
+    """Configuration value types."""
+    BOOLEAN = "boolean"
+    INTEGER = "integer"
+    STRING = "string"
+    UNDEFINED = "undefined"
+
+
+@dataclass
+class ConfigOption:
+    """Configuration option with metadata."""
+    name: str
+    value: Any
+    type: ConfigType
+    line_number: int = 0
+    comment: str = ""
+    
+    def as_bool(self) -> bool:
+        """Get value as boolean."""
+        if self.type == ConfigType.BOOLEAN:
+            return bool(self.value)
+        elif self.type == ConfigType.INTEGER:
+            return self.value != 0
+        elif self.type == ConfigType.STRING:
+            return bool(self.value)
+        return False
+        
+    def as_int(self) -> int:
+        """Get value as integer."""
+        if self.type == ConfigType.INTEGER:
+            return self.value
+        elif self.type == ConfigType.BOOLEAN:
+            return 1 if self.value else 0
+        elif self.type == ConfigType.STRING:
+            try:
+                return int(self.value)
+            except ValueError:
+                return 0
+        return 0
+        
+    def as_str(self) -> str:
+        """Get value as string."""
+        if self.type == ConfigType.STRING:
+            return self.value
+        return str(self.value)
+
+
+class ConfigParser:
+    """Parser for rtconfig.h files."""
+    
+    # Regular expressions for parsing
+    RE_DEFINE = re.compile(r'^\s*#\s*define\s+(\w+)(?:\s+(.*))?', re.MULTILINE)
+    RE_UNDEF = re.compile(r'^\s*#\s*undef\s+(\w+)', re.MULTILINE)
+    RE_IFDEF = re.compile(r'^\s*#\s*ifdef\s+(\w+)', re.MULTILINE)
+    RE_IFNDEF = re.compile(r'^\s*#\s*ifndef\s+(\w+)', re.MULTILINE)
+    RE_ENDIF = re.compile(r'^\s*#\s*endif', re.MULTILINE)
+    RE_COMMENT = re.compile(r'/\*.*?\*/', re.DOTALL)
+    RE_LINE_COMMENT = re.compile(r'//.*$', re.MULTILINE)
+    
+    def __init__(self):
+        self.options: Dict[str, ConfigOption] = {}
+        self.conditions: List[str] = []
+        
+    def parse_file(self, filepath: str) -> Dict[str, ConfigOption]:
+        """
+        Parse configuration file.
+        
+        Args:
+            filepath: Path to rtconfig.h
+            
+        Returns:
+            Dictionary of configuration options
+        """
+        if not os.path.exists(filepath):
+            raise FileNotFoundError(f"Configuration file not found: {filepath}")
+            
+        with open(filepath, 'r', encoding='utf-8') as f:
+            content = f.read()
+            
+        return self.parse_content(content)
+        
+    def parse_content(self, content: str) -> Dict[str, ConfigOption]:
+        """
+        Parse configuration content.
+        
+        Args:
+            content: File content
+            
+        Returns:
+            Dictionary of configuration options
+        """
+        # Remove comments
+        content = self.RE_COMMENT.sub('', content)
+        content = self.RE_LINE_COMMENT.sub('', content)
+        
+        # Parse line by line
+        lines = content.split('\n')
+        for i, line in enumerate(lines):
+            self._parse_line(line, i + 1)
+            
+        return self.options
+        
+    def _parse_line(self, line: str, line_number: int) -> None:
+        """Parse a single line."""
+        # Check for #define
+        match = self.RE_DEFINE.match(line)
+        if match:
+            name = match.group(1)
+            value = match.group(2) if match.group(2) else '1'
+            
+            # Parse value
+            parsed_value, value_type = self._parse_value(value.strip())
+            
+            # Create option
+            option = ConfigOption(
+                name=name,
+                value=parsed_value,
+                type=value_type,
+                line_number=line_number
+            )
+            
+            self.options[name] = option
+            return
+            
+        # Check for #undef
+        match = self.RE_UNDEF.match(line)
+        if match:
+            name = match.group(1)
+            if name in self.options:
+                del self.options[name]
+            return
+            
+    def _parse_value(self, value: str) -> tuple:
+        """
+        Parse configuration value.
+        
+        Returns:
+            Tuple of (parsed_value, ConfigType)
+        """
+        if not value or value == '1':
+            return (True, ConfigType.BOOLEAN)
+            
+        # Try integer
+        try:
+            return (int(value, 0), ConfigType.INTEGER)  # Support hex/octal
+        except ValueError:
+            pass
+            
+        # Try string (remove quotes)
+        if value.startswith('"') and value.endswith('"'):
+            return (value[1:-1], ConfigType.STRING)
+            
+        # Default to string
+        return (value, ConfigType.STRING)
+
+
+class ConfigManager:
+    """
+    Configuration manager for build system.
+    
+    This class manages configuration options and provides dependency checking.
+    """
+    
+    def __init__(self):
+        self.parser = ConfigParser()
+        self.options: Dict[str, ConfigOption] = {}
+        self.cache: Dict[str, bool] = {}
+        
+    def load_from_file(self, filepath: str) -> None:
+        """
+        Load configuration from file.
+        
+        Args:
+            filepath: Path to rtconfig.h
+        """
+        self.options = self.parser.parse_file(filepath)
+        self.cache.clear()  # Clear dependency cache
+        
+    def get_option(self, name: str) -> Optional[ConfigOption]:
+        """
+        Get configuration option.
+        
+        Args:
+            name: Option name
+            
+        Returns:
+            ConfigOption or None
+        """
+        return self.options.get(name)
+        
+    def get_value(self, name: str, default: Any = None) -> Any:
+        """
+        Get configuration value.
+        
+        Args:
+            name: Option name
+            default: Default value if not found
+            
+        Returns:
+            Configuration value
+        """
+        option = self.options.get(name)
+        if option:
+            return option.value
+        return default
+        
+    def get_dependency(self, depend: Union[str, List[str]]) -> bool:
+        """
+        Check if dependency is satisfied.
+        
+        Args:
+            depend: Single dependency or list of dependencies
+            
+        Returns:
+            True if all dependencies are satisfied
+        """
+        # Handle empty dependency
+        if not depend:
+            return True
+            
+        # Convert to list
+        if isinstance(depend, str):
+            depend = [depend]
+            
+        # Check cache
+        cache_key = ','.join(sorted(depend))
+        if cache_key in self.cache:
+            return self.cache[cache_key]
+            
+        # Check all dependencies (AND logic)
+        result = all(self._check_single_dependency(d) for d in depend)
+        
+        # Cache result
+        self.cache[cache_key] = result
+        return result
+        
+    def _check_single_dependency(self, name: str) -> bool:
+        """Check a single dependency."""
+        option = self.options.get(name)
+        if not option:
+            return False
+            
+        # For RT-Thread, any defined macro is considered True
+        # except if explicitly set to 0
+        if option.type == ConfigType.INTEGER:
+            return option.value != 0
+        elif option.type == ConfigType.BOOLEAN:
+            return option.value
+        elif option.type == ConfigType.STRING:
+            return bool(option.value)
+            
+        return True
+        
+    def get_all_options(self) -> Dict[str, Any]:
+        """
+        Get all configuration options as a simple dictionary.
+        
+        Returns:
+            Dictionary of option names to values
+        """
+        return {name: opt.value for name, opt in self.options.items()}
+        
+    def validate(self) -> List[str]:
+        """
+        Validate configuration.
+        
+        Returns:
+            List of validation errors
+        """
+        errors = []
+        
+        # Check for common issues
+        if 'RT_NAME_MAX' in self.options:
+            name_max = self.options['RT_NAME_MAX'].as_int()
+            if name_max < 4:
+                errors.append("RT_NAME_MAX should be at least 4")
+                
+        if 'RT_THREAD_PRIORITY_MAX' in self.options:
+            prio_max = self.options['RT_THREAD_PRIORITY_MAX'].as_int()
+            if prio_max not in [8, 32, 256]:
+                errors.append("RT_THREAD_PRIORITY_MAX should be 8, 32, or 256")
+                
+        return errors

+ 176 - 0
tools/ng/core.py

@@ -0,0 +1,176 @@
+# -*- coding: utf-8 -*-
+"""
+Core module for RT-Thread build system.
+
+This module provides the central BuildContext class that manages the build state
+and coordinates between different components.
+"""
+
+import os
+import logging
+from typing import Dict, List, Optional, Any
+from dataclasses import dataclass, field
+
+from .config import ConfigManager
+from .project import ProjectRegistry
+from .toolchain import ToolchainManager
+from .generator import GeneratorRegistry
+from .utils import PathService
+
+
+class BuildContext:
+    """
+    Central build context that manages all build-related state.
+    
+    This class replaces the global variables in building.py with a proper
+    object-oriented design while maintaining compatibility.
+    """
+    
+    # Class variable to store the current context (for backward compatibility)
+    _current_context: Optional['BuildContext'] = None
+    
+    def __init__(self, root_directory: str):
+        """
+        Initialize build context.
+        
+        Args:
+            root_directory: RT-Thread root directory path
+        """
+        self.root_directory = os.path.abspath(root_directory)
+        self.bsp_directory = os.getcwd()
+        
+        # Initialize managers
+        self.config_manager = ConfigManager()
+        self.project_registry = ProjectRegistry()
+        self.toolchain_manager = ToolchainManager()
+        self.generator_registry = GeneratorRegistry()
+        self.path_service = PathService(self.bsp_directory)
+        
+        # Build environment
+        self.environment = None
+        self.build_options = {}
+        
+        # Logging
+        self.logger = self._setup_logger()
+        
+        # Set as current context
+        BuildContext._current_context = self
+        
+    @classmethod
+    def get_current(cls) -> Optional['BuildContext']:
+        """Get the current build context."""
+        return cls._current_context
+        
+    @classmethod
+    def set_current(cls, context: Optional['BuildContext']) -> None:
+        """Set the current build context."""
+        cls._current_context = context
+        
+    def _setup_logger(self) -> logging.Logger:
+        """Setup logger for build system."""
+        logger = logging.getLogger('rtthread.build')
+        if not logger.handlers:
+            handler = logging.StreamHandler()
+            formatter = logging.Formatter('[%(levelname)s] %(message)s')
+            handler.setFormatter(formatter)
+            logger.addHandler(handler)
+            logger.setLevel(logging.INFO)
+        return logger
+        
+    def prepare_environment(self, env) -> None:
+        """
+        Prepare the build environment.
+        
+        Args:
+            env: SCons Environment object
+        """
+        self.environment = env
+        
+        # Set environment variables
+        env['RTT_ROOT'] = self.root_directory
+        env['BSP_ROOT'] = self.bsp_directory
+        
+        # Add to Python path
+        import sys
+        tools_path = os.path.join(self.root_directory, 'tools')
+        if tools_path not in sys.path:
+            sys.path.insert(0, tools_path)
+            
+        self.logger.debug(f"Prepared environment with RTT_ROOT={self.root_directory}")
+        
+    def load_configuration(self, config_file: str = 'rtconfig.h') -> None:
+        """
+        Load configuration from rtconfig.h.
+        
+        Args:
+            config_file: Path to configuration file
+        """
+        config_path = os.path.join(self.bsp_directory, config_file)
+        if os.path.exists(config_path):
+            self.config_manager.load_from_file(config_path)
+            self.build_options = self.config_manager.get_all_options()
+            self.logger.info(f"Loaded configuration from {config_file}")
+        else:
+            self.logger.warning(f"Configuration file {config_file} not found")
+            
+    def get_dependency(self, depend: Any) -> bool:
+        """
+        Check if dependency is satisfied.
+        
+        Args:
+            depend: Dependency name or list of names
+            
+        Returns:
+            True if dependency is satisfied
+        """
+        return self.config_manager.get_dependency(depend)
+        
+    def register_project_group(self, group) -> None:
+        """
+        Register a project group.
+        
+        Args:
+            group: ProjectGroup instance
+        """
+        self.project_registry.register_group(group)
+        
+    def merge_groups(self) -> List:
+        """
+        Merge all registered project groups.
+        
+        Returns:
+            List of build objects
+        """
+        return self.project_registry.merge_groups(self.environment)
+
+
+@dataclass
+class BuildOptions:
+    """Build options container."""
+    verbose: bool = False
+    strict: bool = False
+    target: Optional[str] = None
+    jobs: int = 1
+    clean: bool = False
+    
+    
+@dataclass 
+class ProjectInfo:
+    """Project information for generators."""
+    name: str = "rtthread"
+    target_name: str = "rtthread.elf"
+    
+    # File collections
+    source_files: List[str] = field(default_factory=list)
+    include_paths: List[str] = field(default_factory=list)
+    defines: Dict[str, str] = field(default_factory=dict)
+    
+    # Compiler options
+    cflags: str = ""
+    cxxflags: str = ""
+    asflags: str = ""
+    ldflags: str = ""
+    
+    # Libraries
+    libs: List[str] = field(default_factory=list)
+    lib_paths: List[str] = field(default_factory=list)

+ 304 - 0
tools/ng/environment.py

@@ -0,0 +1,304 @@
+# -*- coding: utf-8 -*-
+"""
+Environment extensions for RT-Thread build system.
+
+This module provides methods that are injected into the SCons Environment object
+to provide RT-Thread-specific functionality.
+"""
+
+import os
+from typing import List, Union, Dict, Any, Optional
+from SCons.Script import *
+
+from .core import BuildContext
+from .project import ProjectGroup
+
+
+class RTEnv:
+    """
+    RT-Thread environment extensions (RTEnv).
+    
+    This class provides methods that are added to the SCons Environment object.
+    """
+    
+    @staticmethod
+    def inject_methods(env):
+        """
+        Inject RT-Thread methods into SCons Environment.
+        
+        Args:
+            env: SCons Environment object
+        """
+        # Core build methods
+        env.AddMethod(RTEnv.DefineGroup, 'DefineGroup')
+        env.AddMethod(RTEnv.GetDepend, 'GetDepend')
+        env.AddMethod(RTEnv.SrcRemove, 'SrcRemove')
+        env.AddMethod(RTEnv.GetCurrentDir, 'GetCurrentDir')
+        env.AddMethod(RTEnv.BuildPackage, 'BuildPackage')
+        
+        # Utility methods
+        env.AddMethod(RTEnv.Glob, 'GlobFiles')
+        env.AddMethod(RTEnv.GetBuildOptions, 'GetBuildOptions')
+        env.AddMethod(RTEnv.GetContext, 'GetContext')
+        
+        # Path utilities
+        env.AddMethod(RTEnv.GetRTTRoot, 'GetRTTRoot')
+        env.AddMethod(RTEnv.GetBSPRoot, 'GetBSPRoot')
+        
+    @staticmethod
+    def DefineGroup(env, name: str, src: List[str], depend: Any = None, **kwargs) -> List:
+        """
+        Define a component group.
+        
+        This method maintains compatibility with the original DefineGroup function
+        while using the new object-oriented implementation.
+        
+        Args:
+            env: SCons Environment
+            name: Group name
+            src: Source file list
+            depend: Dependency conditions
+            **kwargs: Additional parameters (CPPPATH, CPPDEFINES, etc.)
+            
+        Returns:
+            List of build objects
+        """
+        context = BuildContext.get_current()
+        if not context:
+            raise RuntimeError("BuildContext not initialized")
+            
+        # Check dependencies
+        if depend and not env.GetDepend(depend):
+            return []
+            
+        # Process source files
+        if isinstance(src, str):
+            src = [src]
+            
+        # Create project group
+        group = ProjectGroup(
+            name=name,
+            sources=src,
+            dependencies=depend if isinstance(depend, list) else [depend] if depend else [],
+            environment=env
+        )
+        
+        # Process parameters
+        group.include_paths = kwargs.get('CPPPATH', [])
+        group.defines = kwargs.get('CPPDEFINES', {})
+        group.cflags = kwargs.get('CFLAGS', '')
+        group.cxxflags = kwargs.get('CXXFLAGS', '')
+        group.local_cflags = kwargs.get('LOCAL_CFLAGS', '')
+        group.local_cxxflags = kwargs.get('LOCAL_CXXFLAGS', '')
+        group.local_include_paths = kwargs.get('LOCAL_CPPPATH', [])
+        group.local_defines = kwargs.get('LOCAL_CPPDEFINES', {})
+        group.libs = kwargs.get('LIBS', [])
+        group.lib_paths = kwargs.get('LIBPATH', [])
+        
+        # Build objects
+        objects = group.build(env)
+        
+        # Register group
+        context.register_project_group(group)
+        
+        return objects
+        
+    @staticmethod
+    def GetDepend(env, depend: Any) -> bool:
+        """
+        Check if dependency is satisfied.
+        
+        Args:
+            env: SCons Environment
+            depend: Dependency name or list of names
+            
+        Returns:
+            True if dependency is satisfied
+        """
+        context = BuildContext.get_current()
+        if not context:
+            # Fallback to checking environment variables
+            if isinstance(depend, str):
+                return env.get(depend, False)
+            elif isinstance(depend, list):
+                return all(env.get(d, False) for d in depend)
+            return False
+            
+        return context.get_dependency(depend)
+        
+    @staticmethod
+    def SrcRemove(env, src: List[str], remove: List[str]) -> None:
+        """
+        Remove files from source list.
+        
+        Args:
+            env: SCons Environment
+            src: Source file list (modified in place)
+            remove: Files to remove
+        """
+        if not isinstance(remove, list):
+            remove = [remove]
+            
+        for item in remove:
+            # Handle both exact matches and pattern matches
+            if item in src:
+                src.remove(item)
+            else:
+                # Try pattern matching
+                import fnmatch
+                to_remove = [f for f in src if fnmatch.fnmatch(f, item)]
+                for f in to_remove:
+                    src.remove(f)
+                    
+    @staticmethod
+    def GetCurrentDir(env) -> str:
+        """
+        Get current directory.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            Current directory path
+        """
+        return Dir('.').abspath
+        
+    @staticmethod
+    def BuildPackage(env, package_path: str = None) -> List:
+        """
+        Build package from package.json.
+        
+        Args:
+            env: SCons Environment
+            package_path: Path to package.json or directory containing it
+            
+        Returns:
+            List of build objects
+        """
+        import json
+        
+        # Find package.json
+        if package_path is None:
+            package_path = 'package.json'
+        elif os.path.isdir(package_path):
+            package_path = os.path.join(package_path, 'package.json')
+            
+        if not os.path.exists(package_path):
+            env.GetContext().logger.error(f"Package file not found: {package_path}")
+            return []
+            
+        # Load package definition
+        with open(package_path, 'r') as f:
+            package = json.load(f)
+            
+        # Process package
+        name = package.get('name', 'unnamed')
+        dependencies = package.get('dependencies', {})
+        
+        # Check main dependency
+        if 'RT_USING_' + name.upper() not in dependencies:
+            main_depend = 'RT_USING_' + name.upper().replace('-', '_')
+        else:
+            main_depend = list(dependencies.keys())[0]
+            
+        if not env.GetDepend(main_depend):
+            return []
+            
+        # Collect sources
+        src = []
+        include_paths = []
+        
+        sources = package.get('sources', {})
+        for category, config in sources.items():
+            # Check condition
+            condition = config.get('condition')
+            if condition and not eval(condition, {'env': env, 'GetDepend': env.GetDepend}):
+                continue
+                
+            # Add source files
+            source_files = config.get('source_files', [])
+            for pattern in source_files:
+                src.extend(env.Glob(pattern))
+                
+            # Add header paths
+            header_path = config.get('header_path', [])
+            include_paths.extend(header_path)
+            
+        # Create group
+        return env.DefineGroup(name, src, depend=main_depend, CPPPATH=include_paths)
+        
+    @staticmethod
+    def Glob(env, pattern: str) -> List[str]:
+        """
+        Enhanced glob with better error handling.
+        
+        Args:
+            env: SCons Environment
+            pattern: File pattern
+            
+        Returns:
+            List of matching files
+        """
+        try:
+            files = Glob(pattern, strings=True)
+            return sorted(files)  # Sort for consistent ordering
+        except Exception as e:
+            context = BuildContext.get_current()
+            if context:
+                context.logger.warning(f"Glob pattern '{pattern}' failed: {e}")
+            return []
+            
+    @staticmethod
+    def GetBuildOptions(env) -> Dict[str, Any]:
+        """
+        Get build options.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            Dictionary of build options
+        """
+        context = BuildContext.get_current()
+        if context:
+            return context.build_options
+        return {}
+        
+    @staticmethod
+    def GetContext(env) -> Optional[BuildContext]:
+        """
+        Get current build context.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            BuildContext instance or None
+        """
+        return BuildContext.get_current()
+        
+    @staticmethod
+    def GetRTTRoot(env) -> str:
+        """
+        Get RT-Thread root directory.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            RT-Thread root path
+        """
+        return env.get('RTT_ROOT', '')
+        
+    @staticmethod
+    def GetBSPRoot(env) -> str:
+        """
+        Get BSP root directory.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            BSP root path
+        """
+        return env.get('BSP_ROOT', '')

+ 368 - 0
tools/ng/generator.py

@@ -0,0 +1,368 @@
+# -*- coding: utf-8 -*-
+"""
+Project generator framework for RT-Thread build system.
+
+This module provides the base classes for project generators (MDK, IAR, VS Code, etc.).
+"""
+
+import os
+import shutil
+import json
+import xml.etree.ElementTree as ET
+from abc import ABC, abstractmethod
+from typing import Dict, List, Any, Optional
+from dataclasses import dataclass
+
+from .utils import PathService
+
+
+@dataclass
+class GeneratorConfig:
+    """Configuration for project generators."""
+    output_dir: str
+    project_name: str = "rtthread"
+    target_name: str = "rtthread.elf"
+    
+    
+class ProjectGenerator(ABC):
+    """Abstract base class for project generators."""
+    
+    def __init__(self, config: GeneratorConfig):
+        self.config = config
+        self.path_service = PathService(os.getcwd())
+        
+    @abstractmethod
+    def get_name(self) -> str:
+        """Get generator name."""
+        pass
+        
+    @abstractmethod
+    def generate(self, context, project_info: Dict[str, Any]) -> bool:
+        """
+        Generate project files.
+        
+        Args:
+            context: BuildContext instance
+            project_info: Project information from registry
+            
+        Returns:
+            True if successful
+        """
+        pass
+        
+    @abstractmethod
+    def clean(self) -> bool:
+        """
+        Clean generated files.
+        
+        Returns:
+            True if successful
+        """
+        pass
+        
+    def _ensure_output_dir(self) -> None:
+        """Ensure output directory exists."""
+        os.makedirs(self.config.output_dir, exist_ok=True)
+        
+    def _copy_template(self, template_name: str, output_name: str = None) -> str:
+        """
+        Copy template file to output directory.
+        
+        Args:
+            template_name: Template file name
+            output_name: Output file name (defaults to template_name)
+            
+        Returns:
+            Output file path
+        """
+        if output_name is None:
+            output_name = template_name
+            
+        template_dir = os.path.join(os.path.dirname(__file__), '..', 'targets')
+        template_path = os.path.join(template_dir, template_name)
+        output_path = os.path.join(self.config.output_dir, output_name)
+        
+        if os.path.exists(template_path):
+            shutil.copy2(template_path, output_path)
+            return output_path
+        else:
+            raise FileNotFoundError(f"Template not found: {template_path}")
+
+
+class VscodeGenerator(ProjectGenerator):
+    """Visual Studio Code project generator."""
+    
+    def get_name(self) -> str:
+        return "vscode"
+        
+    def generate(self, context, project_info: Dict[str, Any]) -> bool:
+        """Generate VS Code project files."""
+        self._ensure_output_dir()
+        
+        # Create .vscode directory
+        vscode_dir = os.path.join(self.config.output_dir, '.vscode')
+        os.makedirs(vscode_dir, exist_ok=True)
+        
+        # Generate c_cpp_properties.json
+        self._generate_cpp_properties(vscode_dir, context, project_info)
+        
+        # Generate tasks.json
+        self._generate_tasks(vscode_dir, context)
+        
+        # Generate launch.json
+        self._generate_launch(vscode_dir, context)
+        
+        # Generate settings.json
+        self._generate_settings(vscode_dir)
+        
+        return True
+        
+    def clean(self) -> bool:
+        """Clean VS Code files."""
+        vscode_dir = os.path.join(self.config.output_dir, '.vscode')
+        if os.path.exists(vscode_dir):
+            shutil.rmtree(vscode_dir)
+        return True
+        
+    def _generate_cpp_properties(self, vscode_dir: str, context, project_info: Dict) -> None:
+        """Generate c_cpp_properties.json."""
+        # Get toolchain info
+        toolchain = context.toolchain_manager.get_current()
+        compiler_path = ""
+        if toolchain and toolchain.info:
+            if toolchain.get_name() == "gcc":
+                compiler_path = os.path.join(toolchain.info.path, toolchain.info.prefix + "gcc")
+                
+        config = {
+            "configurations": [
+                {
+                    "name": "RT-Thread",
+                    "includePath": [
+                        "${workspaceFolder}/**"
+                    ] + project_info.get('all_includes', []),
+                    "defines": [f"{k}={v}" if v != '1' else k 
+                              for k, v in project_info.get('all_defines', {}).items()],
+                    "compilerPath": compiler_path,
+                    "cStandard": "c99",
+                    "cppStandard": "c++11",
+                    "intelliSenseMode": "gcc-arm" if "arm" in compiler_path else "gcc-x64"
+                }
+            ],
+            "version": 4
+        }
+        
+        output_path = os.path.join(vscode_dir, 'c_cpp_properties.json')
+        with open(output_path, 'w') as f:
+            json.dump(config, f, indent=4)
+            
+    def _generate_tasks(self, vscode_dir: str, context) -> None:
+        """Generate tasks.json."""
+        tasks = {
+            "version": "2.0.0",
+            "tasks": [
+                {
+                    "label": "build",
+                    "type": "shell",
+                    "command": "scons",
+                    "problemMatcher": "$gcc",
+                    "group": {
+                        "kind": "build",
+                        "isDefault": True
+                    }
+                },
+                {
+                    "label": "clean",
+                    "type": "shell",
+                    "command": "scons -c",
+                    "problemMatcher": "$gcc"
+                },
+                {
+                    "label": "rebuild",
+                    "type": "shell",
+                    "command": "scons -c && scons",
+                    "problemMatcher": "$gcc"
+                }
+            ]
+        }
+        
+        output_path = os.path.join(vscode_dir, 'tasks.json')
+        with open(output_path, 'w') as f:
+            json.dump(tasks, f, indent=4)
+            
+    def _generate_launch(self, vscode_dir: str, context) -> None:
+        """Generate launch.json."""
+        launch = {
+            "version": "0.2.0",
+            "configurations": [
+                {
+                    "name": "Cortex Debug",
+                    "type": "cortex-debug",
+                    "request": "launch",
+                    "servertype": "openocd",
+                    "cwd": "${workspaceRoot}",
+                    "executable": "${workspaceRoot}/" + self.config.target_name,
+                    "device": "STM32F103C8",
+                    "configFiles": [
+                        "interface/stlink-v2.cfg",
+                        "target/stm32f1x.cfg"
+                    ]
+                }
+            ]
+        }
+        
+        output_path = os.path.join(vscode_dir, 'launch.json')
+        with open(output_path, 'w') as f:
+            json.dump(launch, f, indent=4)
+            
+    def _generate_settings(self, vscode_dir: str) -> None:
+        """Generate settings.json."""
+        settings = {
+            "files.associations": {
+                "*.h": "c",
+                "*.c": "c",
+                "*.cpp": "cpp",
+                "*.cc": "cpp",
+                "*.cxx": "cpp"
+            },
+            "C_Cpp.errorSquiggles": "Enabled"
+        }
+        
+        output_path = os.path.join(vscode_dir, 'settings.json')
+        with open(output_path, 'w') as f:
+            json.dump(settings, f, indent=4)
+
+
+class CMakeGenerator(ProjectGenerator):
+    """CMake project generator."""
+    
+    def get_name(self) -> str:
+        return "cmake"
+        
+    def generate(self, context, project_info: Dict[str, Any]) -> bool:
+        """Generate CMakeLists.txt."""
+        self._ensure_output_dir()
+        
+        # Get toolchain info
+        toolchain = context.toolchain_manager.get_current()
+        
+        lines = [
+            "cmake_minimum_required(VERSION 3.10)",
+            "",
+            "# RT-Thread CMake Project",
+            f"project({self.config.project_name} C CXX ASM)",
+            "",
+            "# C Standard",
+            "set(CMAKE_C_STANDARD 99)",
+            "set(CMAKE_CXX_STANDARD 11)",
+            ""
+        ]
+        
+        # Toolchain configuration
+        if toolchain and toolchain.get_name() == "gcc":
+            lines.extend([
+                "# Toolchain",
+                f"set(CMAKE_C_COMPILER {toolchain.info.prefix}gcc)",
+                f"set(CMAKE_CXX_COMPILER {toolchain.info.prefix}g++)",
+                f"set(CMAKE_ASM_COMPILER {toolchain.info.prefix}gcc)",
+                ""
+            ])
+            
+        # Include directories
+        lines.extend([
+            "# Include directories",
+            "include_directories("
+        ])
+        for inc in project_info.get('all_includes', []):
+            lines.append(f"    {inc}")
+        lines.extend([")", ""])
+        
+        # Definitions
+        lines.extend([
+            "# Definitions",
+            "add_definitions("
+        ])
+        for k, v in project_info.get('all_defines', {}).items():
+            if v == '1':
+                lines.append(f"    -D{k}")
+            else:
+                lines.append(f"    -D{k}={v}")
+        lines.extend([")", ""])
+        
+        # Source files
+        lines.extend([
+            "# Source files",
+            "set(SOURCES"
+        ])
+        for src in project_info.get('all_sources', []):
+            lines.append(f"    {src}")
+        lines.extend([")", ""])
+        
+        # Executable
+        lines.extend([
+            "# Executable",
+            f"add_executable(${{PROJECT_NAME}} ${{SOURCES}})",
+            ""
+        ])
+        
+        # Libraries
+        if project_info.get('all_libs'):
+            lines.extend([
+                "# Libraries",
+                f"target_link_libraries(${{PROJECT_NAME}}"
+            ])
+            for lib in project_info['all_libs']:
+                lines.append(f"    {lib}")
+            lines.extend([")", ""])
+            
+        # Write file
+        output_path = os.path.join(self.config.output_dir, 'CMakeLists.txt')
+        with open(output_path, 'w') as f:
+            f.write('\n'.join(lines))
+            
+        return True
+        
+    def clean(self) -> bool:
+        """Clean CMake files."""
+        files_to_remove = ['CMakeLists.txt', 'CMakeCache.txt']
+        dirs_to_remove = ['CMakeFiles']
+        
+        for file in files_to_remove:
+            file_path = os.path.join(self.config.output_dir, file)
+            if os.path.exists(file_path):
+                os.remove(file_path)
+                
+        for dir in dirs_to_remove:
+            dir_path = os.path.join(self.config.output_dir, dir)
+            if os.path.exists(dir_path):
+                shutil.rmtree(dir_path)
+                
+        return True
+
+
+class GeneratorRegistry:
+    """Registry for project generators."""
+    
+    def __init__(self):
+        self.generators: Dict[str, type] = {}
+        self._register_default_generators()
+        
+    def _register_default_generators(self) -> None:
+        """Register default generators."""
+        self.register("vscode", VscodeGenerator)
+        self.register("vsc", VscodeGenerator)  # Alias
+        self.register("cmake", CMakeGenerator)
+        
+    def register(self, name: str, generator_class: type) -> None:
+        """Register a generator class."""
+        self.generators[name] = generator_class
+        
+    def create_generator(self, name: str, config: GeneratorConfig) -> ProjectGenerator:
+        """Create a generator instance."""
+        if name not in self.generators:
+            raise ValueError(f"Unknown generator: {name}")
+            
+        return self.generators[name](config)
+        
+    def list_generators(self) -> List[str]:
+        """List available generators."""
+        return list(self.generators.keys())

+ 178 - 0
tools/ng/integration_example.py

@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+"""
+Example of minimal changes needed in building.py to integrate the new OOP system.
+
+This file shows the exact changes that would be made to the original building.py.
+"""
+
+# =============================================================================
+# CHANGES TO ADD AT THE BEGINNING OF building.py
+# =============================================================================
+
+"""
+# Add after the imports section in building.py (around line 45)
+
+# Try to import new OOP system
+try:
+    from ng.adapter import (
+        init_build_context,
+        inject_environment_methods,
+        load_rtconfig as ng_load_rtconfig,
+        MergeGroups as ng_MergeGroups
+    )
+    NG_AVAILABLE = True
+except ImportError:
+    NG_AVAILABLE = False
+"""
+
+# =============================================================================
+# CHANGES IN PrepareBuilding FUNCTION
+# =============================================================================
+
+"""
+# Add these lines in PrepareBuilding function after setting up Env (around line 70)
+
+    # Initialize new OOP system if available
+    if NG_AVAILABLE:
+        # Initialize build context
+        ng_context = init_build_context(Rtt_Root)
+        
+        # Inject methods into environment
+        inject_environment_methods(Env)
+        
+        # Store context reference
+        Env['__NG_Context'] = ng_context
+"""
+
+# =============================================================================
+# CHANGES AFTER PARSING rtconfig.h
+# =============================================================================
+
+"""
+# Add after parsing rtconfig.h (around line 430)
+
+    # Load configuration into new system
+    if NG_AVAILABLE and 'rtconfig.h' in os.listdir(Bsp_Root):
+        ng_load_rtconfig('rtconfig.h')
+"""
+
+# =============================================================================
+# ENHANCED DefineGroup FUNCTION
+# =============================================================================
+
+"""
+# Replace the original DefineGroup function (around line 565) with:
+
+def DefineGroup(name, src, depend, **parameters):
+    global Env
+    if Env is None:
+        return []
+    
+    # Try to use new implementation if available
+    if NG_AVAILABLE and hasattr(Env, 'DefineGroup'):
+        return Env.DefineGroup(name, src, depend, **parameters)
+    
+    # Original implementation continues below...
+    # [Keep all the original DefineGroup code here]
+"""
+
+# =============================================================================
+# ENHANCED GetDepend FUNCTION  
+# =============================================================================
+
+"""
+# Replace the original GetDepend function (around line 655) with:
+
+def GetDepend(depend):
+    global Env
+    
+    # Try to use new implementation if available
+    if NG_AVAILABLE and Env and hasattr(Env, 'GetDepend'):
+        return Env.GetDepend(depend)
+    
+    # Original implementation continues below...
+    # [Keep all the original GetDepend code here]
+"""
+
+# =============================================================================
+# ENHANCED MergeGroup FUNCTION
+# =============================================================================
+
+"""
+# Replace the original MergeGroup function (around line 700) with:
+
+def MergeGroup(src_group, group):
+    # Try to use new implementation if available
+    if NG_AVAILABLE and Env and hasattr(Env, '__NG_Context'):
+        context = Env['__NG_Context']
+        if context:
+            # Register groups with new system
+            from ng.project import ProjectGroup
+            for g in group:
+                if 'name' in g:
+                    pg = ProjectGroup(
+                        name=g['name'],
+                        sources=g.get('src', []),
+                        dependencies=[],
+                        environment=Env
+                    )
+                    context.register_project_group(pg)
+    
+    # Original implementation continues below...
+    # [Keep all the original MergeGroup code here]
+"""
+
+# =============================================================================
+# EXAMPLE USAGE IN SCONSCRIPT
+# =============================================================================
+
+def example_sconscript():
+    """
+    Example of how to use the new features in a SConscript file.
+    """
+    sconscript_content = '''
+from building import *
+
+# Get environment
+env = GetEnvironment()
+
+# Method 1: Use new environment methods (if available)
+if hasattr(env, 'DefineGroup'):
+    # New OOP style
+    src = env.GlobFiles('*.c')
+    group = env.DefineGroup('MyComponent', src, depend=['RT_USING_XXX'])
+else:
+    # Fallback to traditional style
+    src = Glob('*.c')
+    group = DefineGroup('MyComponent', src, depend=['RT_USING_XXX'])
+
+# Method 2: Always compatible style
+src = Glob('*.c')
+group = DefineGroup('MyComponent', src, depend=['RT_USING_XXX'])
+
+Return('group')
+'''
+    return sconscript_content
+
+# =============================================================================
+# MINIMAL CHANGES SUMMARY
+# =============================================================================
+
+"""
+Summary of changes needed in building.py:
+
+1. Add imports at the beginning (5 lines)
+2. Add initialization in PrepareBuilding (6 lines)  
+3. Add config loading after rtconfig.h parsing (3 lines)
+4. Modify DefineGroup to check for new method (3 lines)
+5. Modify GetDepend to check for new method (3 lines)
+6. Enhance MergeGroup to register with new system (15 lines)
+
+Total: ~35 lines of code added/modified in building.py
+
+Benefits:
+- Fully backward compatible
+- Opt-in design (works even if ng module is not present)
+- Gradual migration path
+- No changes needed in existing SConscript files
+"""

+ 260 - 0
tools/ng/project.py

@@ -0,0 +1,260 @@
+# -*- coding: utf-8 -*-
+"""
+Project and group management for RT-Thread build system.
+
+This module provides classes for managing project groups and their compilation.
+"""
+
+import os
+from typing import List, Dict, Any, Optional
+from dataclasses import dataclass, field
+from SCons.Script import *
+
+
+@dataclass
+class ProjectGroup:
+    """
+    Represents a project group (component).
+    
+    This class encapsulates the information from DefineGroup calls.
+    """
+    name: str
+    sources: List[str]
+    dependencies: List[str] = field(default_factory=list)
+    environment: Any = None  # SCons Environment
+    
+    # Paths and defines
+    include_paths: List[str] = field(default_factory=list)
+    defines: Dict[str, str] = field(default_factory=dict)
+    
+    # Compiler flags
+    cflags: str = ""
+    cxxflags: str = ""
+    asflags: str = ""
+    ldflags: str = ""
+    
+    # Local options (only for this group)
+    local_cflags: str = ""
+    local_cxxflags: str = ""
+    local_include_paths: List[str] = field(default_factory=list)
+    local_defines: Dict[str, str] = field(default_factory=dict)
+    
+    # Libraries
+    libs: List[str] = field(default_factory=list)
+    lib_paths: List[str] = field(default_factory=list)
+    
+    # Build objects
+    objects: List[Any] = field(default_factory=list)
+    
+    def build(self, env) -> List:
+        """
+        Build the group and return objects.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            List of build objects
+        """
+        if not self.sources:
+            return []
+            
+        # Clone environment if we have local options
+        build_env = env
+        if self._has_local_options():
+            build_env = env.Clone()
+            self._apply_local_options(build_env)
+            
+        # Apply global options
+        self._apply_global_options(build_env)
+        
+        # Build objects
+        self.objects = []
+        for src in self.sources:
+            if isinstance(src, str):
+                # Build single file
+                obj = build_env.Object(src)
+                self.objects.extend(obj if isinstance(obj, list) else [obj])
+            else:
+                # Already a Node
+                self.objects.append(src)
+                
+        return self.objects
+        
+    def _has_local_options(self) -> bool:
+        """Check if group has local options."""
+        return bool(
+            self.local_cflags or
+            self.local_cxxflags or
+            self.local_include_paths or
+            self.local_defines
+        )
+        
+    def _apply_local_options(self, env) -> None:
+        """Apply local options to environment."""
+        if self.local_cflags:
+            env.AppendUnique(CFLAGS=self.local_cflags.split())
+            
+        if self.local_cxxflags:
+            env.AppendUnique(CXXFLAGS=self.local_cxxflags.split())
+            
+        if self.local_include_paths:
+            paths = [os.path.abspath(p) for p in self.local_include_paths]
+            env.AppendUnique(CPPPATH=paths)
+            
+        if self.local_defines:
+            env.AppendUnique(CPPDEFINES=self.local_defines)
+            
+    def _apply_global_options(self, env) -> None:
+        """Apply global options to environment."""
+        # These options affect dependent groups too
+        if self.include_paths:
+            paths = [os.path.abspath(p) for p in self.include_paths]
+            env.AppendUnique(CPPPATH=paths)
+            
+        if self.defines:
+            env.AppendUnique(CPPDEFINES=self.defines)
+            
+        if self.cflags and 'CFLAGS' not in env:
+            env['CFLAGS'] = self.cflags
+            
+        if self.cxxflags and 'CXXFLAGS' not in env:
+            env['CXXFLAGS'] = self.cxxflags
+            
+        if self.libs:
+            env.AppendUnique(LIBS=self.libs)
+            
+        if self.lib_paths:
+            paths = [os.path.abspath(p) for p in self.lib_paths]
+            env.AppendUnique(LIBPATH=paths)
+            
+    def get_info(self) -> Dict[str, Any]:
+        """
+        Get group information for project generators.
+        
+        Returns:
+            Dictionary with group information
+        """
+        return {
+            'name': self.name,
+            'sources': self.sources,
+            'include_paths': self.include_paths + self.local_include_paths,
+            'defines': {**self.defines, **self.local_defines},
+            'cflags': f"{self.cflags} {self.local_cflags}".strip(),
+            'cxxflags': f"{self.cxxflags} {self.local_cxxflags}".strip(),
+            'libs': self.libs,
+            'lib_paths': self.lib_paths
+        }
+
+
+class ProjectRegistry:
+    """
+    Registry for all project groups.
+    
+    This class manages all registered project groups and provides
+    methods for querying and merging them.
+    """
+    
+    def __init__(self):
+        self.groups: List[ProjectGroup] = []
+        self._group_index: Dict[str, ProjectGroup] = {}
+        
+    def register_group(self, group: ProjectGroup) -> None:
+        """
+        Register a project group.
+        
+        Args:
+            group: ProjectGroup instance
+        """
+        self.groups.append(group)
+        self._group_index[group.name] = group
+        
+    def get_group(self, name: str) -> Optional[ProjectGroup]:
+        """
+        Get group by name.
+        
+        Args:
+            name: Group name
+            
+        Returns:
+            ProjectGroup or None
+        """
+        return self._group_index.get(name)
+        
+    def get_all_groups(self) -> List[ProjectGroup]:
+        """Get all registered groups."""
+        return self.groups.copy()
+        
+    def get_groups_by_dependency(self, dependency: str) -> List[ProjectGroup]:
+        """
+        Get groups that depend on a specific macro.
+        
+        Args:
+            dependency: Dependency name
+            
+        Returns:
+            List of matching groups
+        """
+        return [g for g in self.groups if dependency in g.dependencies]
+        
+    def merge_groups(self, env) -> List:
+        """
+        Merge all groups into a single list of objects.
+        
+        Args:
+            env: SCons Environment
+            
+        Returns:
+            List of all build objects
+        """
+        all_objects = []
+        
+        for group in self.groups:
+            if group.objects:
+                all_objects.extend(group.objects)
+                
+        return all_objects
+        
+    def get_project_info(self) -> Dict[str, Any]:
+        """
+        Get complete project information for generators.
+        
+        Returns:
+            Dictionary with project information
+        """
+        # Collect all unique values
+        all_sources = []
+        all_includes = set()
+        all_defines = {}
+        all_libs = []
+        all_lib_paths = set()
+        
+        for group in self.groups:
+            info = group.get_info()
+            
+            # Sources
+            all_sources.extend(info['sources'])
+            
+            # Include paths
+            all_includes.update(info['include_paths'])
+            
+            # Defines
+            all_defines.update(info['defines'])
+            
+            # Libraries
+            all_libs.extend(info['libs'])
+            all_lib_paths.update(info['lib_paths'])
+            
+        return {
+            'groups': [g.get_info() for g in self.groups],
+            'all_sources': all_sources,
+            'all_includes': sorted(list(all_includes)),
+            'all_defines': all_defines,
+            'all_libs': all_libs,
+            'all_lib_paths': sorted(list(all_lib_paths))
+        }
+        
+    def clear(self) -> None:
+        """Clear all registered groups."""
+        self.groups.clear()
+        self._group_index.clear()

+ 396 - 0
tools/ng/toolchain.py

@@ -0,0 +1,396 @@
+# -*- coding: utf-8 -*-
+"""
+Toolchain management for RT-Thread build system.
+
+This module provides abstraction for different toolchains (GCC, Keil, IAR, etc.).
+"""
+
+import os
+import shutil
+import subprocess
+from abc import ABC, abstractmethod
+from typing import Dict, List, Optional, Tuple
+from dataclasses import dataclass
+
+
+@dataclass
+class ToolchainInfo:
+    """Toolchain information."""
+    name: str
+    version: str
+    path: str
+    prefix: str = ""
+    suffix: str = ""
+    
+    
+class Toolchain(ABC):
+    """Abstract base class for toolchains."""
+    
+    def __init__(self):
+        self.info = None
+        
+    @abstractmethod
+    def get_name(self) -> str:
+        """Get toolchain name."""
+        pass
+        
+    @abstractmethod
+    def detect(self) -> bool:
+        """Detect if toolchain is available."""
+        pass
+        
+    @abstractmethod
+    def configure_environment(self, env) -> None:
+        """Configure SCons environment for this toolchain."""
+        pass
+        
+    @abstractmethod
+    def get_compile_flags(self, cpu: str, fpu: str = None, float_abi: str = None) -> Dict[str, str]:
+        """Get compilation flags for target CPU."""
+        pass
+        
+    def get_version(self) -> Optional[str]:
+        """Get toolchain version."""
+        return self.info.version if self.info else None
+        
+    def _run_command(self, cmd: List[str]) -> Tuple[int, str, str]:
+        """Run command and return (returncode, stdout, stderr)."""
+        try:
+            result = subprocess.run(cmd, capture_output=True, text=True)
+            return result.returncode, result.stdout, result.stderr
+        except Exception as e:
+            return -1, "", str(e)
+
+
+class GccToolchain(Toolchain):
+    """GCC toolchain implementation."""
+    
+    def __init__(self, prefix: str = ""):
+        super().__init__()
+        self.prefix = prefix or "arm-none-eabi-"
+        
+    def get_name(self) -> str:
+        return "gcc"
+        
+    def detect(self) -> bool:
+        """Detect GCC toolchain."""
+        gcc_path = shutil.which(self.prefix + "gcc")
+        if not gcc_path:
+            return False
+            
+        # Get version
+        ret, stdout, _ = self._run_command([gcc_path, "--version"])
+        if ret == 0:
+            lines = stdout.split('\n')
+            if lines:
+                version = lines[0].split()[-1]
+                self.info = ToolchainInfo(
+                    name="gcc",
+                    version=version,
+                    path=os.path.dirname(gcc_path),
+                    prefix=self.prefix
+                )
+                return True
+                
+        return False
+        
+    def configure_environment(self, env) -> None:
+        """Configure environment for GCC."""
+        env['CC'] = self.prefix + 'gcc'
+        env['CXX'] = self.prefix + 'g++'
+        env['AS'] = self.prefix + 'gcc'
+        env['AR'] = self.prefix + 'ar'
+        env['LINK'] = self.prefix + 'gcc'
+        env['SIZE'] = self.prefix + 'size'
+        env['OBJDUMP'] = self.prefix + 'objdump'
+        env['OBJCPY'] = self.prefix + 'objcopy'
+        
+        # Set default flags
+        env['ARFLAGS'] = '-rc'
+        env['ASFLAGS'] = '-x assembler-with-cpp'
+        
+        # Path
+        if self.info and self.info.path:
+            env.PrependENVPath('PATH', self.info.path)
+            
+    def get_compile_flags(self, cpu: str, fpu: str = None, float_abi: str = None) -> Dict[str, str]:
+        """Get GCC compilation flags."""
+        flags = {
+            'CFLAGS': [],
+            'CXXFLAGS': [],
+            'ASFLAGS': [],
+            'LDFLAGS': []
+        }
+        
+        # CPU flags
+        cpu_flags = {
+            'cortex-m0': '-mcpu=cortex-m0 -mthumb',
+            'cortex-m0+': '-mcpu=cortex-m0plus -mthumb',
+            'cortex-m3': '-mcpu=cortex-m3 -mthumb',
+            'cortex-m4': '-mcpu=cortex-m4 -mthumb',
+            'cortex-m7': '-mcpu=cortex-m7 -mthumb',
+            'cortex-m23': '-mcpu=cortex-m23 -mthumb',
+            'cortex-m33': '-mcpu=cortex-m33 -mthumb',
+            'cortex-a7': '-mcpu=cortex-a7',
+            'cortex-a9': '-mcpu=cortex-a9'
+        }
+        
+        if cpu in cpu_flags:
+            base_flags = cpu_flags[cpu]
+            for key in ['CFLAGS', 'CXXFLAGS', 'ASFLAGS']:
+                flags[key].append(base_flags)
+                
+        # FPU flags
+        if fpu:
+            fpu_flag = f'-mfpu={fpu}'
+            for key in ['CFLAGS', 'CXXFLAGS']:
+                flags[key].append(fpu_flag)
+                
+        # Float ABI
+        if float_abi:
+            abi_flag = f'-mfloat-abi={float_abi}'
+            for key in ['CFLAGS', 'CXXFLAGS']:
+                flags[key].append(abi_flag)
+                
+        # Common flags
+        common_flags = ['-ffunction-sections', '-fdata-sections']
+        flags['CFLAGS'].extend(common_flags)
+        flags['CXXFLAGS'].extend(common_flags)
+        
+        # Linker flags
+        flags['LDFLAGS'].extend(['-Wl,--gc-sections'])
+        
+        # Convert lists to strings
+        return {k: ' '.join(v) for k, v in flags.items()}
+
+
+class ArmccToolchain(Toolchain):
+    """ARM Compiler (Keil) toolchain implementation."""
+    
+    def get_name(self) -> str:
+        return "armcc"
+        
+    def detect(self) -> bool:
+        """Detect ARM Compiler toolchain."""
+        armcc_path = shutil.which("armcc")
+        if not armcc_path:
+            # Try common Keil installation paths
+            keil_paths = [
+                r"C:\Keil_v5\ARM\ARMCC\bin",
+                r"C:\Keil\ARM\ARMCC\bin",
+                "/opt/arm/bin"
+            ]
+            for path in keil_paths:
+                test_path = os.path.join(path, "armcc")
+                if os.path.exists(test_path):
+                    armcc_path = test_path
+                    break
+                    
+        if not armcc_path:
+            return False
+            
+        # Get version
+        ret, stdout, _ = self._run_command([armcc_path, "--version"])
+        if ret == 0:
+            lines = stdout.split('\n')
+            for line in lines:
+                if "ARM Compiler" in line:
+                    version = line.split()[-1]
+                    self.info = ToolchainInfo(
+                        name="armcc",
+                        version=version,
+                        path=os.path.dirname(armcc_path)
+                    )
+                    return True
+                    
+        return False
+        
+    def configure_environment(self, env) -> None:
+        """Configure environment for ARM Compiler."""
+        env['CC'] = 'armcc'
+        env['CXX'] = 'armcc'
+        env['AS'] = 'armasm'
+        env['AR'] = 'armar'
+        env['LINK'] = 'armlink'
+        
+        # ARM Compiler specific settings
+        env['ARCOM'] = '$AR --create $TARGET $SOURCES'
+        env['LIBPREFIX'] = ''
+        env['LIBSUFFIX'] = '.lib'
+        env['LIBLINKPREFIX'] = ''
+        env['LIBLINKSUFFIX'] = '.lib'
+        env['LIBDIRPREFIX'] = '--userlibpath '
+        
+        # Path
+        if self.info and self.info.path:
+            env.PrependENVPath('PATH', self.info.path)
+            
+    def get_compile_flags(self, cpu: str, fpu: str = None, float_abi: str = None) -> Dict[str, str]:
+        """Get ARM Compiler flags."""
+        flags = {
+            'CFLAGS': [],
+            'CXXFLAGS': [],
+            'ASFLAGS': [],
+            'LDFLAGS': []
+        }
+        
+        # CPU selection
+        cpu_map = {
+            'cortex-m0': '--cpu Cortex-M0',
+            'cortex-m0+': '--cpu Cortex-M0+',
+            'cortex-m3': '--cpu Cortex-M3',
+            'cortex-m4': '--cpu Cortex-M4',
+            'cortex-m7': '--cpu Cortex-M7'
+        }
+        
+        if cpu in cpu_map:
+            cpu_flag = cpu_map[cpu]
+            for key in flags:
+                flags[key].append(cpu_flag)
+                
+        # Common flags
+        flags['CFLAGS'].extend(['--c99', '--gnu'])
+        flags['CXXFLAGS'].extend(['--cpp', '--gnu'])
+        
+        return {k: ' '.join(v) for k, v in flags.items()}
+
+
+class IarToolchain(Toolchain):
+    """IAR toolchain implementation."""
+    
+    def get_name(self) -> str:
+        return "iar"
+        
+    def detect(self) -> bool:
+        """Detect IAR toolchain."""
+        iccarm_path = shutil.which("iccarm")
+        if not iccarm_path:
+            # Try common IAR installation paths
+            iar_paths = [
+                r"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\bin",
+                r"C:\Program Files\IAR Systems\Embedded Workbench 8.0\arm\bin",
+                "/opt/iar/bin"
+            ]
+            for path in iar_paths:
+                test_path = os.path.join(path, "iccarm.exe" if os.name == 'nt' else "iccarm")
+                if os.path.exists(test_path):
+                    iccarm_path = test_path
+                    break
+                    
+        if not iccarm_path:
+            return False
+            
+        self.info = ToolchainInfo(
+            name="iar",
+            version="8.x",  # IAR version detection is complex
+            path=os.path.dirname(iccarm_path)
+        )
+        return True
+        
+    def configure_environment(self, env) -> None:
+        """Configure environment for IAR."""
+        env['CC'] = 'iccarm'
+        env['CXX'] = 'iccarm'
+        env['AS'] = 'iasmarm'
+        env['AR'] = 'iarchive'
+        env['LINK'] = 'ilinkarm'
+        
+        # IAR specific settings
+        env['LIBPREFIX'] = ''
+        env['LIBSUFFIX'] = '.a'
+        env['LIBLINKPREFIX'] = ''
+        env['LIBLINKSUFFIX'] = '.a'
+        
+        # Path
+        if self.info and self.info.path:
+            env.PrependENVPath('PATH', self.info.path)
+            
+    def get_compile_flags(self, cpu: str, fpu: str = None, float_abi: str = None) -> Dict[str, str]:
+        """Get IAR flags."""
+        flags = {
+            'CFLAGS': [],
+            'CXXFLAGS': [],
+            'ASFLAGS': [],
+            'LDFLAGS': []
+        }
+        
+        # CPU selection
+        cpu_map = {
+            'cortex-m0': '--cpu=Cortex-M0',
+            'cortex-m0+': '--cpu=Cortex-M0+',
+            'cortex-m3': '--cpu=Cortex-M3',
+            'cortex-m4': '--cpu=Cortex-M4',
+            'cortex-m7': '--cpu=Cortex-M7'
+        }
+        
+        if cpu in cpu_map:
+            cpu_flag = cpu_map[cpu]
+            flags['CFLAGS'].append(cpu_flag)
+            flags['CXXFLAGS'].append(cpu_flag)
+            
+        # Common flags
+        flags['CFLAGS'].extend(['-e', '--dlib_config', 'DLib_Config_Normal.h'])
+        
+        return {k: ' '.join(v) for k, v in flags.items()}
+
+
+class ToolchainManager:
+    """Manager for toolchain selection and configuration."""
+    
+    def __init__(self):
+        self.toolchains: Dict[str, Toolchain] = {}
+        self.current_toolchain: Optional[Toolchain] = None
+        self._register_default_toolchains()
+        
+    def _register_default_toolchains(self) -> None:
+        """Register default toolchains."""
+        # Try to detect available toolchains
+        toolchain_classes = [
+            (GccToolchain, ['arm-none-eabi-', 'riscv32-unknown-elf-', 'riscv64-unknown-elf-']),
+            (ArmccToolchain, ['']),
+            (IarToolchain, [''])
+        ]
+        
+        for toolchain_class, prefixes in toolchain_classes:
+            for prefix in prefixes:
+                if toolchain_class == GccToolchain:
+                    tc = toolchain_class(prefix)
+                else:
+                    tc = toolchain_class()
+                    
+                if tc.detect():
+                    name = f"{tc.get_name()}-{prefix}" if prefix else tc.get_name()
+                    self.register_toolchain(name, tc)
+                    
+    def register_toolchain(self, name: str, toolchain: Toolchain) -> None:
+        """Register a toolchain."""
+        self.toolchains[name] = toolchain
+        
+    def select_toolchain(self, name: str) -> Toolchain:
+        """Select a toolchain by name."""
+        if name not in self.toolchains:
+            # Try to create it
+            if name == 'gcc':
+                tc = GccToolchain()
+            elif name == 'armcc' or name == 'keil':
+                tc = ArmccToolchain()
+            elif name == 'iar':
+                tc = IarToolchain()
+            else:
+                raise ValueError(f"Unknown toolchain: {name}")
+                
+            if tc.detect():
+                self.register_toolchain(name, tc)
+            else:
+                raise RuntimeError(f"Toolchain '{name}' not found")
+                
+        self.current_toolchain = self.toolchains[name]
+        return self.current_toolchain
+        
+    def get_current(self) -> Optional[Toolchain]:
+        """Get current toolchain."""
+        return self.current_toolchain
+        
+    def list_toolchains(self) -> List[str]:
+        """List available toolchains."""
+        return list(self.toolchains.keys())

+ 339 - 0
tools/ng/utils.py

@@ -0,0 +1,339 @@
+# -*- coding: utf-8 -*-
+"""
+Utility functions for RT-Thread build system.
+
+This module provides common utility functions used throughout the build system.
+"""
+
+import os
+import sys
+import platform
+from typing import List, Tuple, Optional
+
+
+class PathService:
+    """Service for path manipulation and normalization."""
+    
+    def __init__(self, base_path: str = None):
+        self.base_path = base_path or os.getcwd()
+        
+    def normalize_path(self, path: str) -> str:
+        """
+        Normalize path for cross-platform compatibility.
+        
+        Args:
+            path: Path to normalize
+            
+        Returns:
+            Normalized path
+        """
+        # Convert to absolute path if relative
+        if not os.path.isabs(path):
+            path = os.path.abspath(os.path.join(self.base_path, path))
+            
+        # Normalize separators
+        path = os.path.normpath(path)
+        
+        # Convert to forward slashes for consistency
+        if platform.system() == 'Windows':
+            path = path.replace('\\', '/')
+            
+        return path
+        
+    def make_relative(self, path: str, base: str = None) -> str:
+        """
+        Make path relative to base.
+        
+        Args:
+            path: Path to make relative
+            base: Base path (defaults to self.base_path)
+            
+        Returns:
+            Relative path
+        """
+        if base is None:
+            base = self.base_path
+            
+        path = self.normalize_path(path)
+        base = self.normalize_path(base)
+        
+        try:
+            rel_path = os.path.relpath(path, base)
+            # Convert to forward slashes
+            if platform.system() == 'Windows':
+                rel_path = rel_path.replace('\\', '/')
+            return rel_path
+        except ValueError:
+            # Different drives on Windows
+            return path
+            
+    def split_path(self, path: str) -> List[str]:
+        """
+        Split path into components.
+        
+        Args:
+            path: Path to split
+            
+        Returns:
+            List of path components
+        """
+        path = self.normalize_path(path)
+        parts = []
+        
+        while True:
+            head, tail = os.path.split(path)
+            if tail:
+                parts.insert(0, tail)
+            if head == path:  # Reached root
+                if head:
+                    parts.insert(0, head)
+                break
+            path = head
+            
+        return parts
+        
+    def common_prefix(self, paths: List[str]) -> str:
+        """
+        Find common prefix of multiple paths.
+        
+        Args:
+            paths: List of paths
+            
+        Returns:
+            Common prefix path
+        """
+        if not paths:
+            return ""
+            
+        # Normalize all paths
+        normalized = [self.normalize_path(p) for p in paths]
+        
+        # Find common prefix
+        prefix = os.path.commonpath(normalized)
+        
+        return self.normalize_path(prefix)
+
+
+class PlatformInfo:
+    """Platform and system information."""
+    
+    @staticmethod
+    def get_platform() -> str:
+        """Get platform name (Windows, Linux, Darwin)."""
+        return platform.system()
+        
+    @staticmethod
+    def get_architecture() -> str:
+        """Get system architecture."""
+        return platform.machine()
+        
+    @staticmethod
+    def is_windows() -> bool:
+        """Check if running on Windows."""
+        return platform.system() == 'Windows'
+        
+    @staticmethod
+    def is_linux() -> bool:
+        """Check if running on Linux."""
+        return platform.system() == 'Linux'
+        
+    @staticmethod
+    def is_macos() -> bool:
+        """Check if running on macOS."""
+        return platform.system() == 'Darwin'
+        
+    @staticmethod
+    def get_python_version() -> Tuple[int, int, int]:
+        """Get Python version tuple."""
+        return sys.version_info[:3]
+        
+    @staticmethod
+    def check_python_version(min_version: Tuple[int, int]) -> bool:
+        """
+        Check if Python version meets minimum requirement.
+        
+        Args:
+            min_version: Minimum version tuple (major, minor)
+            
+        Returns:
+            True if version is sufficient
+        """
+        current = sys.version_info[:2]
+        return current >= min_version
+
+
+class FileUtils:
+    """File operation utilities."""
+    
+    @staticmethod
+    def read_file(filepath: str, encoding: str = 'utf-8') -> str:
+        """
+        Read file content.
+        
+        Args:
+            filepath: File path
+            encoding: File encoding
+            
+        Returns:
+            File content
+        """
+        with open(filepath, 'r', encoding=encoding) as f:
+            return f.read()
+            
+    @staticmethod
+    def write_file(filepath: str, content: str, encoding: str = 'utf-8') -> None:
+        """
+        Write content to file.
+        
+        Args:
+            filepath: File path
+            content: Content to write
+            encoding: File encoding
+        """
+        # Ensure directory exists
+        directory = os.path.dirname(filepath)
+        if directory:
+            os.makedirs(directory, exist_ok=True)
+            
+        with open(filepath, 'w', encoding=encoding) as f:
+            f.write(content)
+            
+    @staticmethod
+    def copy_file(src: str, dst: str) -> None:
+        """
+        Copy file from src to dst.
+        
+        Args:
+            src: Source file path
+            dst: Destination file path
+        """
+        import shutil
+        
+        # Ensure destination directory exists
+        dst_dir = os.path.dirname(dst)
+        if dst_dir:
+            os.makedirs(dst_dir, exist_ok=True)
+            
+        shutil.copy2(src, dst)
+        
+    @staticmethod
+    def find_files(directory: str, pattern: str, recursive: bool = True) -> List[str]:
+        """
+        Find files matching pattern.
+        
+        Args:
+            directory: Directory to search
+            pattern: File pattern (supports wildcards)
+            recursive: Search recursively
+            
+        Returns:
+            List of matching file paths
+        """
+        import fnmatch
+        
+        matches = []
+        
+        if recursive:
+            for root, dirnames, filenames in os.walk(directory):
+                for filename in filenames:
+                    if fnmatch.fnmatch(filename, pattern):
+                        matches.append(os.path.join(root, filename))
+        else:
+            try:
+                filenames = os.listdir(directory)
+                for filename in filenames:
+                    if fnmatch.fnmatch(filename, pattern):
+                        filepath = os.path.join(directory, filename)
+                        if os.path.isfile(filepath):
+                            matches.append(filepath)
+            except OSError:
+                pass
+                
+        return sorted(matches)
+
+
+class VersionUtils:
+    """Version comparison utilities."""
+    
+    @staticmethod
+    def parse_version(version_str: str) -> Tuple[int, ...]:
+        """
+        Parse version string to tuple.
+        
+        Args:
+            version_str: Version string (e.g., "1.2.3")
+            
+        Returns:
+            Version tuple
+        """
+        try:
+            parts = version_str.split('.')
+            return tuple(int(p) for p in parts if p.isdigit())
+        except (ValueError, AttributeError):
+            return (0,)
+            
+    @staticmethod
+    def compare_versions(v1: str, v2: str) -> int:
+        """
+        Compare two version strings.
+        
+        Args:
+            v1: First version
+            v2: Second version
+            
+        Returns:
+            -1 if v1 < v2, 0 if equal, 1 if v1 > v2
+        """
+        t1 = VersionUtils.parse_version(v1)
+        t2 = VersionUtils.parse_version(v2)
+        
+        # Pad shorter version with zeros
+        if len(t1) < len(t2):
+            t1 = t1 + (0,) * (len(t2) - len(t1))
+        elif len(t2) < len(t1):
+            t2 = t2 + (0,) * (len(t1) - len(t2))
+            
+        if t1 < t2:
+            return -1
+        elif t1 > t2:
+            return 1
+        else:
+            return 0
+            
+    @staticmethod
+    def version_satisfies(version: str, requirement: str) -> bool:
+        """
+        Check if version satisfies requirement.
+        
+        Args:
+            version: Version string
+            requirement: Requirement string (e.g., ">=1.2.0")
+            
+        Returns:
+            True if satisfied
+        """
+        import re
+        
+        # Parse requirement
+        match = re.match(r'([<>=]+)\s*(.+)', requirement)
+        if not match:
+            # Exact match required
+            return version == requirement
+            
+        op, req_version = match.groups()
+        cmp = VersionUtils.compare_versions(version, req_version)
+        
+        if op == '>=':
+            return cmp >= 0
+        elif op == '<=':
+            return cmp <= 0
+        elif op == '>':
+            return cmp > 0
+        elif op == '<':
+            return cmp < 0
+        elif op == '==':
+            return cmp == 0
+        elif op == '!=':
+            return cmp != 0
+        else:
+            return False