Skip to content

Commit 5a2352e

Browse files
authored
[scons] code cleanup for scons script. (#10429)
* [scons] move project_generation to targets; code clean for building.py.
1 parent 8e9872a commit 5a2352e

38 files changed

+895
-349
lines changed

tools/WCS.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,6 @@ def main():
426426
# Print A Nice Message With Each Function and the WCS
427427
print_all_fxns(call_graph)
428428

429-
430-
431-
432429
def ThreadStackStaticAnalysis(env):
433430
print('Start thread stack static analysis...')
434431

tools/building.py

Lines changed: 22 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
# 2024-04-21 Bernard Add toolchain detection in sdk packages
2727
# 2025-01-05 Bernard Add logging as Env['log']
2828
# 2025-03-02 ZhaoCake Add MkDist_Strip
29+
# 2025-01-05 Assistant Refactor SCons PreProcessor patch to independent class
2930

3031
import os
3132
import sys
@@ -39,90 +40,14 @@
3940
from utils import _make_path_relative
4041
from mkdist import do_copy_file
4142
from options import AddOptions
43+
from preprocessor import create_preprocessor_instance
44+
from win32spawn import Win32Spawn
4245

4346
BuildOptions = {}
4447
Projects = []
4548
Rtt_Root = ''
4649
Env = None
4750

48-
# SCons PreProcessor patch
49-
def start_handling_includes(self, t=None):
50-
"""
51-
Causes the PreProcessor object to start processing #import,
52-
#include and #include_next lines.
53-
54-
This method will be called when a #if, #ifdef, #ifndef or #elif
55-
evaluates True, or when we reach the #else in a #if, #ifdef,
56-
#ifndef or #elif block where a condition already evaluated
57-
False.
58-
59-
"""
60-
d = self.dispatch_table
61-
p = self.stack[-1] if self.stack else self.default_table
62-
63-
for k in ('import', 'include', 'include_next', 'define'):
64-
d[k] = p[k]
65-
66-
def stop_handling_includes(self, t=None):
67-
"""
68-
Causes the PreProcessor object to stop processing #import,
69-
#include and #include_next lines.
70-
71-
This method will be called when a #if, #ifdef, #ifndef or #elif
72-
evaluates False, or when we reach the #else in a #if, #ifdef,
73-
#ifndef or #elif block where a condition already evaluated True.
74-
"""
75-
d = self.dispatch_table
76-
d['import'] = self.do_nothing
77-
d['include'] = self.do_nothing
78-
d['include_next'] = self.do_nothing
79-
d['define'] = self.do_nothing
80-
81-
PatchedPreProcessor = SCons.cpp.PreProcessor
82-
PatchedPreProcessor.start_handling_includes = start_handling_includes
83-
PatchedPreProcessor.stop_handling_includes = stop_handling_includes
84-
85-
class Win32Spawn:
86-
def spawn(self, sh, escape, cmd, args, env):
87-
# deal with the cmd build-in commands which cannot be used in
88-
# subprocess.Popen
89-
if cmd == 'del':
90-
for f in args[1:]:
91-
try:
92-
os.remove(f)
93-
except Exception as e:
94-
print('Error removing file: ' + e)
95-
return -1
96-
return 0
97-
98-
import subprocess
99-
100-
newargs = ' '.join(args[1:])
101-
cmdline = cmd + " " + newargs
102-
103-
# Make sure the env is constructed by strings
104-
_e = dict([(k, str(v)) for k, v in env.items()])
105-
106-
# Windows(tm) CreateProcess does not use the env passed to it to find
107-
# the executables. So we have to modify our own PATH to make Popen
108-
# work.
109-
old_path = os.environ['PATH']
110-
os.environ['PATH'] = _e['PATH']
111-
112-
try:
113-
proc = subprocess.Popen(cmdline, env=_e, shell=False)
114-
except Exception as e:
115-
print('Error in calling command:' + cmdline.split(' ')[0])
116-
print('Exception: ' + os.strerror(e.errno))
117-
if (os.strerror(e.errno) == "No such file or directory"):
118-
print ("\nPlease check Toolchains PATH setting.\n")
119-
120-
return e.errno
121-
finally:
122-
os.environ['PATH'] = old_path
123-
124-
return proc.wait()
125-
12651
def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = []):
12752

12853
global BuildOptions
@@ -294,7 +219,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
294219
Env.Append(BUILDERS = {'BuildLib': bld})
295220

296221
# parse rtconfig.h to get used component
297-
PreProcessor = PatchedPreProcessor()
222+
PreProcessor = create_preprocessor_instance()
298223
f = open('rtconfig.h', 'r')
299224
contents = f.read()
300225
f.close()
@@ -433,7 +358,7 @@ def PrepareModuleBuilding(env, root_directory, bsp_directory):
433358
Rtt_Root = root_directory
434359

435360
# parse bsp rtconfig.h to get used component
436-
PreProcessor = PatchedPreProcessor()
361+
PreProcessor = create_preprocessor_instance()
437362
f = open(bsp_directory + '/rtconfig.h', 'r')
438363
contents = f.read()
439364
f.close()
@@ -877,7 +802,7 @@ def local_group(group, objects):
877802
def GenTargetProject(program = None):
878803

879804
if GetOption('target') in ['mdk', 'mdk4', 'mdk5']:
880-
from keil import MDK2Project, MDK4Project, MDK5Project, ARMCC_Version
805+
from targets.keil import MDK2Project, MDK4Project, MDK5Project, ARMCC_Version
881806

882807
if os.path.isfile('template.uvprojx') and GetOption('target') not in ['mdk4']: # Keil5
883808
MDK5Project(GetOption('project-name') + '.uvprojx', Projects)
@@ -895,68 +820,68 @@ def GenTargetProject(program = None):
895820
print("Keil-MDK project has generated successfully!")
896821

897822
if GetOption('target') == 'iar':
898-
from iar import IARProject, IARVersion
823+
from targets.iar import IARProject, IARVersion
899824
print("IAR Version: " + IARVersion())
900825
IARProject(GetOption('project-name') + '.ewp', Projects)
901826
print("IAR project has generated successfully!")
902827

903828
if GetOption('target') == 'vs':
904-
from vs import VSProject
829+
from targets.vs import VSProject
905830
VSProject(GetOption('project-name') + '.vcproj', Projects, program)
906831

907832
if GetOption('target') == 'vs2012':
908-
from vs2012 import VS2012Project
833+
from targets.vs2012 import VS2012Project
909834
VS2012Project(GetOption('project-name') + '.vcxproj', Projects, program)
910835

911836
if GetOption('target') == 'cb':
912-
from codeblocks import CBProject
837+
from targets.codeblocks import CBProject
913838
CBProject(GetOption('project-name') + '.cbp', Projects, program)
914839

915840
if GetOption('target') == 'ua':
916-
from ua import PrepareUA
841+
from targets.ua import PrepareUA
917842
PrepareUA(Projects, Rtt_Root, str(Dir('#')))
918843

919844
if GetOption('target') == 'vsc':
920-
from vsc import GenerateVSCode
845+
from targets.vsc import GenerateVSCode
921846
GenerateVSCode(Env)
922847
if GetOption('cmsispack'):
923848
from vscpyocd import GenerateVSCodePyocdConfig
924849
GenerateVSCodePyocdConfig(GetOption('cmsispack'))
925850

926851
if GetOption('target') == 'cdk':
927-
from cdk import CDKProject
852+
from targets.cdk import CDKProject
928853
CDKProject(GetOption('project-name') + '.cdkproj', Projects)
929854

930855
if GetOption('target') == 'ses':
931-
from ses import SESProject
856+
from targets.ses import SESProject
932857
SESProject(Env)
933858

934859
if GetOption('target') == 'makefile':
935-
from makefile import TargetMakefile
860+
from targets.makefile import TargetMakefile
936861
TargetMakefile(Env)
937862

938863
if GetOption('target') == 'eclipse':
939-
from eclipse import TargetEclipse
864+
from targets.eclipse import TargetEclipse
940865
TargetEclipse(Env, GetOption('reset-project-config'), GetOption('project-name'))
941866

942867
if GetOption('target') == 'codelite':
943-
from codelite import TargetCodelite
868+
from targets.codelite import TargetCodelite
944869
TargetCodelite(Projects, program)
945870

946871
if GetOption('target') == 'cmake' or GetOption('target') == 'cmake-armclang':
947-
from cmake import CMakeProject
872+
from targets.cmake import CMakeProject
948873
CMakeProject(Env, Projects, GetOption('project-name'))
949874

950875
if GetOption('target') == 'xmake':
951-
from xmake import XMakeProject
876+
from targets.xmake import XMakeProject
952877
XMakeProject(Env, Projects)
953878

954879
if GetOption('target') == 'esp-idf':
955-
from esp_idf import ESPIDFProject
880+
from targets.esp_idf import ESPIDFProject
956881
ESPIDFProject(Env, Projects)
957882

958883
if GetOption('target') == 'zig':
959-
from zigbuild import ZigBuildProject
884+
from targets.zigbuild import ZigBuildProject
960885
ZigBuildProject(Env, Projects)
961886

962887
def EndBuilding(target, program = None):
@@ -1069,7 +994,7 @@ def GetVersion():
1069994
rtdef = os.path.join(Rtt_Root, 'include', 'rtdef.h')
1070995

1071996
# parse rtdef.h to get RT-Thread version
1072-
prepcessor = PatchedPreProcessor()
997+
prepcessor = create_preprocessor_instance()
1073998
f = open(rtdef, 'r')
1074999
contents = f.read()
10751000
f.close()
@@ -1109,4 +1034,3 @@ def PackageSConscript(package):
11091034
from package import BuildPackage
11101035

11111036
return BuildPackage(package)
1112-

tools/hello/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Hello Component
2+
3+
这是一个使用package.json配置的RT-Thread组件示例,展示了如何使用package.json来替代传统的SConscript中DefineGroup的方式。
4+
5+
## 文件结构
6+
7+
```
8+
hello/
9+
├── hello.h # 头文件
10+
├── hello.c # 源文件
11+
├── package.json # 组件配置文件
12+
├── SConscript # 构建脚本
13+
└── README.md # 说明文档
14+
```
15+
16+
## package.json配置说明
17+
18+
package.json文件包含了组件的所有构建信息:
19+
20+
- `name`: 组件名称
21+
- `version`: 版本号
22+
- `description`: 组件描述
23+
- `author`: 作者信息
24+
- `license`: 许可证
25+
- `source_files`: 源文件列表
26+
- `CPPPATH`: 头文件搜索路径
27+
- `CPPDEFINES`: 预定义宏
28+
- `depends`: 依赖的组件
29+
30+
## 使用方法
31+
32+
1. 将hello文件夹复制到你的RT-Thread项目的components目录下
33+
2. 在应用代码中包含头文件:
34+
```c
35+
#include "hello.h"
36+
```
37+
3. 调用hello_world函数:
38+
```c
39+
hello_world(); // 输出: Hello World!
40+
```
41+
42+
## 构建过程
43+
44+
SConscript文件会:
45+
1. 导入package.py模块
46+
2. 调用BuildPackage函数处理package.json
47+
3. 自动创建DefineGroup并返回构建对象
48+
49+
这种方式比传统的SConscript更加简洁和易于维护。

tools/hello/SConscript

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from package import *
2+
3+
objs = BuildPackage()
4+
Return('objs')

tools/hello/hello.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) 2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-06-21 Bernard First version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include "hello.h"
13+
14+
/**
15+
* @brief Hello world function implementation
16+
*
17+
* This function prints "Hello World!" to the console using rt_kprintf
18+
*/
19+
void hello_world(void)
20+
{
21+
rt_kprintf("Hello World!\n");
22+
}

tools/hello/hello.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-06-21 Bernard First version
9+
*/
10+
11+
#ifndef __HELLO_H__
12+
#define __HELLO_H__
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
/**
19+
* @brief Hello world function
20+
*
21+
* This function prints "Hello World!" to the console
22+
*/
23+
void hello_world(void);
24+
25+
#ifdef __cplusplus
26+
}
27+
#endif
28+
29+
#endif /* __HELLO_H__ */

tools/hello/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "hello",
3+
"version": "1.0.0",
4+
"description": "Hello World component for RT-Thread",
5+
"author": "RT-Thread Development Team",
6+
"license": "Apache-2.0",
7+
"type": "rt-package",
8+
"source_files": [
9+
"hello.c"
10+
],
11+
"CPPPATH": [
12+
"."
13+
],
14+
"CPPDEFINES": [
15+
"HELLO"
16+
],
17+
"depends": [
18+
""
19+
]
20+
}

0 commit comments

Comments
 (0)