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-04-21 supperthomas add the smart yml support and add env
9
+ #
10
+ import subprocess
11
+ import threading
12
+ import time
13
+ import logging
14
+ import sys
1
15
import os
2
16
import shutil
3
17
import re
@@ -36,7 +50,7 @@ def run_cmd(cmd, output_info=True):
36
50
return output_str_list , res
37
51
38
52
39
- def build_bsp (bsp , scons_args = '' ,name = 'default' ):
53
+ def build_bsp (bsp , scons_args = '' ,name = 'default' , pre_build_commands = None , post_build_command = None , build_check_result = None , bsp_build_env = None ):
40
54
"""
41
55
build bsp.
42
56
@@ -56,21 +70,41 @@ def build_bsp(bsp, scons_args='',name='default'):
56
70
57
71
"""
58
72
success = True
73
+ # 设置环境变量
74
+ if bsp_build_env is not None :
75
+ print ("Setting environment variables:" )
76
+ for key , value in bsp_build_env .items ():
77
+ print (f"{ key } ={ value } " )
78
+ os .environ [key ] = value # 设置环境变量
59
79
os .chdir (rtt_root )
60
80
os .makedirs (f'{ rtt_root } /output/bsp/{ bsp } ' , exist_ok = True )
61
81
if os .path .exists (f"{ rtt_root } /bsp/{ bsp } /Kconfig" ):
62
82
os .chdir (rtt_root )
63
- run_cmd (f'scons -C bsp/{ bsp } --pyconfig-silent' , output_info = False )
83
+ run_cmd (f'scons -C bsp/{ bsp } --pyconfig-silent' , output_info = True )
64
84
65
85
os .chdir (f'{ rtt_root } /bsp/{ bsp } ' )
66
- run_cmd ('pkgs --update-force' , output_info = False )
86
+ run_cmd ('pkgs --update-force' , output_info = True )
67
87
run_cmd ('pkgs --list' )
68
88
69
89
nproc = multiprocessing .cpu_count ()
90
+ if pre_build_commands is not None :
91
+ print ("Pre-build commands:" )
92
+ print (pre_build_commands )
93
+ for command in pre_build_commands :
94
+ print (command )
95
+ output , returncode = run_cmd (command , output_info = True )
96
+ print (output )
97
+ if returncode != 0 :
98
+ print (f"Pre-build command failed: { command } " )
99
+ print (output )
70
100
os .chdir (rtt_root )
101
+ # scons 编译命令
71
102
cmd = f'scons -C bsp/{ bsp } -j{ nproc } { scons_args } ' # --debug=time for debug time
72
- __ , res = run_cmd (cmd , output_info = True )
73
-
103
+ output , res = run_cmd (cmd , output_info = True )
104
+ if build_check_result is not None :
105
+ if res != 0 or not check_output (output , build_check_result ):
106
+ print ("Build failed or build check result not found" )
107
+ print (output )
74
108
if res != 0 :
75
109
success = False
76
110
else :
@@ -83,6 +117,13 @@ def build_bsp(bsp, scons_args='',name='default'):
83
117
shutil .copy (file , f'{ rtt_root } /output/bsp/{ bsp } /{ name .replace ("/" , "_" )} .{ file_type [2 :]} ' )
84
118
85
119
os .chdir (f'{ rtt_root } /bsp/{ bsp } ' )
120
+ if post_build_command is not None :
121
+ for command in post_build_command :
122
+ output , returncode = run_cmd (command , output_info = True )
123
+ print (output )
124
+ if returncode != 0 :
125
+ print (f"Post-build command failed: { command } " )
126
+ print (output )
86
127
run_cmd ('scons -c' , output_info = False )
87
128
88
129
return success
@@ -158,7 +199,17 @@ def build_bsp_attachconfig(bsp, attach_file):
158
199
159
200
return res
160
201
202
+ def check_output (output , check_string ):
203
+ """检查输出中是否包含指定字符串"""
204
+ output_str = '' .join (output ) if isinstance (output , list ) else str (output )
205
+ flag = check_string in output_str
206
+ if flag == True :
207
+ print ('Success: find string ' + check_string )
208
+ else :
209
+ print (output )
210
+ print (f"::error:: can not find string { check_string } output: { output_str } " )
161
211
212
+ return flag
162
213
if __name__ == "__main__" :
163
214
"""
164
215
build all bsp and attach config.
@@ -169,10 +220,12 @@ def build_bsp_attachconfig(bsp, attach_file):
169
220
"""
170
221
failed = 0
171
222
count = 0
223
+ ci_build_run_flag = False
224
+ qemu_timeout_second = 50
172
225
173
226
rtt_root = os .getcwd ()
174
227
srtt_bsp = os .getenv ('SRTT_BSP' ).split (',' )
175
-
228
+ print ( srtt_bsp )
176
229
for bsp in srtt_bsp :
177
230
count += 1
178
231
print (f"::group::Compiling BSP: =={ count } === { bsp } ====" )
@@ -207,26 +260,80 @@ def build_bsp_attachconfig(bsp, attach_file):
207
260
continue
208
261
209
262
config_file = os .path .join (rtt_root , 'bsp' , bsp , '.config' )
210
-
263
+ # 在使用 pre_build_commands 之前,确保它被定义
264
+ pre_build_commands = None
265
+ build_command = None
266
+ post_build_command = None
267
+ qemu_command = None
268
+ build_check_result = None
269
+ commands = None
270
+ check_result = None
271
+ bsp_build_env = None
211
272
for projects in yml_files_content :
212
273
for name , details in projects .items ():
274
+ # 如果是bsp_board_info,读取基本的信息
275
+ if (name == 'bsp_board_info' ):
276
+ print (details )
277
+ pre_build_commands = details .get ("pre_build" ).splitlines ()
278
+ build_command = details .get ("build_cmd" ).splitlines ()
279
+ post_build_command = details .get ("post_build" ).splitlines ()
280
+ qemu_command = details .get ("run_cmd" )
281
+
282
+ if details .get ("kconfig" ) is not None :
283
+ if details .get ("buildcheckresult" ) is not None :
284
+ build_check_result = details .get ("buildcheckresult" )
285
+ else :
286
+ build_check_result = None
287
+ if details .get ("msh_cmd" ) is not None :
288
+ commands = details .get ("msh_cmd" ).splitlines ()
289
+ else :
290
+ msh_cmd = None
291
+ if details .get ("checkresult" ) is not None :
292
+ check_result = details .get ("checkresult" )
293
+ else :
294
+ check_result = None
295
+ if details .get ("ci_build_run_flag" ) is not None :
296
+ ci_build_run_flag = details .get ("ci_build_run_flag" )
297
+ else :
298
+ ci_build_run_flag = None
299
+ if details .get ("pre_build" ) is not None :
300
+ pre_build_commands = details .get ("pre_build" ).splitlines ()
301
+ if details .get ("env" ) is not None :
302
+ bsp_build_env = details .get ("env" )
303
+ else :
304
+ bsp_build_env = None
305
+ if details .get ("build_cmd" ) is not None :
306
+ build_command = details .get ("build_cmd" ).splitlines ()
307
+ else :
308
+ build_command = None
309
+ if details .get ("post_build" ) is not None :
310
+ post_build_command = details .get ("post_build" ).splitlines ()
311
+ if details .get ("run_cmd" ) is not None :
312
+ qemu_command = details .get ("run_cmd" )
313
+ else :
314
+ qemu_command = None
213
315
count += 1
214
316
config_bacakup = config_file + '.origin'
215
317
shutil .copyfile (config_file , config_bacakup )
318
+ #加载yml中的配置放到.config文件
216
319
with open (config_file , 'a' ) as destination :
217
320
if details .get ("kconfig" ) is None :
321
+ #如果没有Kconfig,读取下一个配置
218
322
continue
219
323
if (projects .get (name ) is not None ):
324
+ # 获取Kconfig中所有的信息
220
325
detail_list = get_details_and_dependencies ([name ],projects )
221
326
for line in detail_list :
222
327
destination .write (line + '\n ' )
223
328
scons_arg = []
329
+ #如果配置中有scons_arg
224
330
if details .get ('scons_arg' ) is not None :
225
331
for line in details .get ('scons_arg' ):
226
332
scons_arg .append (line )
227
333
scons_arg_str = ' ' .join (scons_arg ) if scons_arg else ' '
228
334
print (f"::group::\t Compiling yml project: =={ count } ==={ name } =scons_arg={ scons_arg_str } ==" )
229
- res = build_bsp (bsp , scons_arg_str ,name = name )
335
+ # #开始编译bsp
336
+ res = build_bsp (bsp , scons_arg_str ,name = name ,pre_build_commands = pre_build_commands ,post_build_command = post_build_command ,build_check_result = build_check_result ,bsp_build_env = bsp_build_env )
230
337
if not res :
231
338
print (f"::error::build { bsp } { name } failed." )
232
339
add_summary (f'\t - ❌ build { bsp } { name } failed.' )
@@ -235,11 +342,15 @@ def build_bsp_attachconfig(bsp, attach_file):
235
342
add_summary (f'\t - ✅ build { bsp } { name } success.' )
236
343
print ("::endgroup::" )
237
344
345
+
238
346
shutil .copyfile (config_bacakup , config_file )
239
347
os .remove (config_bacakup )
240
348
349
+
350
+
241
351
attach_dir = os .path .join (rtt_root , 'bsp' , bsp , '.ci/attachconfig' )
242
352
attach_list = []
353
+ #这里是旧的文件方式
243
354
for root , dirs , files in os .walk (attach_dir ):
244
355
for file in files :
245
356
if file .endswith ('attach' ):
0 commit comments