[action/ci] add qemu-pre-build-and-post-build for RT_SMART build (#10203)

[action/ci] add qemu-pre-build-and-post-build for RT_SMART build
This commit is contained in:
Supper Thomas 2025-04-27 17:31:51 +08:00 committed by GitHub
parent b4e051a890
commit 427e177526
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 175 additions and 14 deletions

View File

@ -69,7 +69,6 @@
"RTT_TOOL_CHAIN": "sourcery-arm",
"SUB_RTT_BSP": [
"phytium/aarch32",
"qemu-vexpress-a9",
"airm2m/air32f103",
"acm32/acm32f0x0-nucleo",
"acm32/acm32f0x0-nucleo",
@ -457,6 +456,14 @@
"nrf5x/nrf52840",
"nrf5x/nrf5340"
]
},
{
"RTT_BSP": "arm-none-bsp-smart",
"RTT_TOOL_CHAIN": "sourcery-arm",
"RTT_SMART_TOOL_CHAIN": "arm-linux-musleabi",
"SUB_RTT_BSP": [
"qemu-vexpress-a9"
]
}
]
}

View File

@ -216,6 +216,14 @@ jobs:
pip3 install esptool
echo "RTT_EXEC_PATH=/opt/riscv32-esp-elf/bin" >> $GITHUB_ENV
- name: Install Arm Musl ToolChains
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-arm' && matrix.legs.RTT_SMART_TOOL_CHAIN == 'arm-linux-musleabi' && success() }}
shell: bash
run: |
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/arm-linux-musleabi_for_x86_64-pc-linux-gnu_stable.tar.bz2
sudo tar xjf arm-linux-musleabi_for_x86_64-pc-linux-gnu_stable.tar.bz2 -C /opt
/opt/arm-linux-musleabi_for_x86_64-pc-linux-gnu/bin/arm-linux-musleabi-gcc --version
- name: Install Simulator Tools
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'gcc' && success() }}
run: |

View File

@ -1,3 +1,14 @@
bsp_board_info:
arch: arm
toolchain: arm-none-eabi-gcc
pre_build: |
scons --version
build_cmd: |
scons -j8
post_build: |
scons --version
run_cmd: ./qemu-nographic.sh
qemu_flag: true
# ------ PERIPHERAL CI ------
peripheral.UARTv2:
kconfig:
@ -15,15 +26,39 @@ peripheral.LVGL:
- CONFIG_BSP_USING_LVGL=y
# ------ online-packages CI ------
online-packages.tools.coremark:
kconfig:
- CONFIG_PKG_USING_COREMARK=y
- CONFIG_COREMARK_ITERATIONS=36000
pre_build: |
scons --version
build_cmd: |
scons -j8
post_build: |
scons --version
ci_build_run_flag : true
buildcheckresult: "core_main" #检查编译的log中是否有匹配字
msh_cmd: |
ps
version
core_mark
msh_cmd_timeout: 60
checkresult: 'CoreMark 1.0' #检查执行过程中的log是否有匹配字
online-packages.misc.entertainment.tetris:
kconfig:
- CONFIG_PKG_USING_TETRIS=y
online-packages.misc.entertainment.2048:
kconfig:
- CONFIG_PKG_USING_2048=y
online-packages.ai.llmchat:
# ------ RT_SMART PART ------
rt_smart.base:
env:
RTT_CC_PREFIX: arm-linux-musleabi-
RTT_EXEC_PATH: /opt/arm-linux-musleabi_for_x86_64-pc-linux-gnu/bin
pre_build: |
echo $RTT_CC_PREFIX
kconfig:
- CONFIG_WEBCLIENT_USING_MBED_TLS=y
- CONFIG_BSP_DRV_EMAC=y
- CONFIG_PKG_USING_LLMCHAT=y
- CONFIG_PKG_LLM_API_KEY="sk-xxxxxx"
- CONFIG_RT_USING_SMART=y
- CONFIG_RT_USING_MEMHEAP=y
- CONFIG_RT_USING_DFS_V2=y

View File

@ -1,3 +1,17 @@
#
# Copyright (c) 2025, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2025-04-21 supperthomas add the smart yml support and add env
#
import subprocess
import threading
import time
import logging
import sys
import os
import shutil
import re
@ -36,7 +50,7 @@ def run_cmd(cmd, output_info=True):
return output_str_list, res
def build_bsp(bsp, scons_args='',name='default'):
def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_build_command=None,build_check_result = None,bsp_build_env=None):
"""
build bsp.
@ -56,21 +70,41 @@ def build_bsp(bsp, scons_args='',name='default'):
"""
success = True
# 设置环境变量
if bsp_build_env is not None:
print("Setting environment variables:")
for key, value in bsp_build_env.items():
print(f"{key}={value}")
os.environ[key] = value # 设置环境变量
os.chdir(rtt_root)
os.makedirs(f'{rtt_root}/output/bsp/{bsp}', exist_ok=True)
if os.path.exists(f"{rtt_root}/bsp/{bsp}/Kconfig"):
os.chdir(rtt_root)
run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent', output_info=False)
run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent', output_info=True)
os.chdir(f'{rtt_root}/bsp/{bsp}')
run_cmd('pkgs --update-force', output_info=False)
run_cmd('pkgs --update-force', output_info=True)
run_cmd('pkgs --list')
nproc = multiprocessing.cpu_count()
if pre_build_commands is not None:
print("Pre-build commands:")
print(pre_build_commands)
for command in pre_build_commands:
print(command)
output, returncode = run_cmd(command, output_info=True)
print(output)
if returncode != 0:
print(f"Pre-build command failed: {command}")
print(output)
os.chdir(rtt_root)
# scons 编译命令
cmd = f'scons -C bsp/{bsp} -j{nproc} {scons_args}' # --debug=time for debug time
__, res = run_cmd(cmd, output_info=True)
output, res = run_cmd(cmd, output_info=True)
if build_check_result is not None:
if res != 0 or not check_output(output, build_check_result):
print("Build failed or build check result not found")
print(output)
if res != 0:
success = False
else:
@ -83,6 +117,13 @@ def build_bsp(bsp, scons_args='',name='default'):
shutil.copy(file, f'{rtt_root}/output/bsp/{bsp}/{name.replace("/", "_")}.{file_type[2:]}')
os.chdir(f'{rtt_root}/bsp/{bsp}')
if post_build_command is not None:
for command in post_build_command:
output, returncode = run_cmd(command, output_info=True)
print(output)
if returncode != 0:
print(f"Post-build command failed: {command}")
print(output)
run_cmd('scons -c', output_info=False)
return success
@ -158,7 +199,17 @@ def build_bsp_attachconfig(bsp, attach_file):
return res
def check_output(output, check_string):
"""检查输出中是否包含指定字符串"""
output_str = ''.join(output) if isinstance(output, list) else str(output)
flag = check_string in output_str
if flag == True:
print('Success: find string ' + check_string)
else:
print(output)
print(f"::error:: can not find string {check_string} output: {output_str}")
return flag
if __name__ == "__main__":
"""
build all bsp and attach config.
@ -169,10 +220,12 @@ if __name__ == "__main__":
"""
failed = 0
count = 0
ci_build_run_flag = False
qemu_timeout_second = 50
rtt_root = os.getcwd()
srtt_bsp = os.getenv('SRTT_BSP').split(',')
print(srtt_bsp)
for bsp in srtt_bsp:
count += 1
print(f"::group::Compiling BSP: =={count}=== {bsp} ====")
@ -207,26 +260,80 @@ if __name__ == "__main__":
continue
config_file = os.path.join(rtt_root, 'bsp', bsp, '.config')
# 在使用 pre_build_commands 之前,确保它被定义
pre_build_commands = None
build_command = None
post_build_command = None
qemu_command = None
build_check_result = None
commands = None
check_result = None
bsp_build_env = None
for projects in yml_files_content:
for name, details in projects.items():
# 如果是bsp_board_info读取基本的信息
if(name == 'bsp_board_info'):
print(details)
pre_build_commands = details.get("pre_build").splitlines()
build_command = details.get("build_cmd").splitlines()
post_build_command = details.get("post_build").splitlines()
qemu_command = details.get("run_cmd")
if details.get("kconfig") is not None:
if details.get("buildcheckresult") is not None:
build_check_result = details.get("buildcheckresult")
else:
build_check_result = None
if details.get("msh_cmd") is not None:
commands = details.get("msh_cmd").splitlines()
else:
msh_cmd = None
if details.get("checkresult") is not None:
check_result = details.get("checkresult")
else:
check_result = None
if details.get("ci_build_run_flag") is not None:
ci_build_run_flag = details.get("ci_build_run_flag")
else:
ci_build_run_flag = None
if details.get("pre_build") is not None:
pre_build_commands = details.get("pre_build").splitlines()
if details.get("env") is not None:
bsp_build_env = details.get("env")
else:
bsp_build_env = None
if details.get("build_cmd") is not None:
build_command = details.get("build_cmd").splitlines()
else:
build_command = None
if details.get("post_build") is not None:
post_build_command = details.get("post_build").splitlines()
if details.get("run_cmd") is not None:
qemu_command = details.get("run_cmd")
else:
qemu_command = None
count += 1
config_bacakup = config_file+'.origin'
shutil.copyfile(config_file, config_bacakup)
#加载yml中的配置放到.config文件
with open(config_file, 'a') as destination:
if details.get("kconfig") is None:
#如果没有Kconfig读取下一个配置
continue
if(projects.get(name) is not None):
# 获取Kconfig中所有的信息
detail_list=get_details_and_dependencies([name],projects)
for line in detail_list:
destination.write(line + '\n')
scons_arg=[]
#如果配置中有scons_arg
if details.get('scons_arg') is not None:
for line in details.get('scons_arg'):
scons_arg.append(line)
scons_arg_str=' '.join(scons_arg) if scons_arg else ' '
print(f"::group::\tCompiling yml project: =={count}==={name}=scons_arg={scons_arg_str}==")
res = build_bsp(bsp, scons_arg_str,name=name)
# #开始编译bsp
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)
if not res:
print(f"::error::build {bsp} {name} failed.")
add_summary(f'\t- ❌ build {bsp} {name} failed.')
@ -235,11 +342,15 @@ if __name__ == "__main__":
add_summary(f'\t- ✅ build {bsp} {name} success.')
print("::endgroup::")
shutil.copyfile(config_bacakup, config_file)
os.remove(config_bacakup)
attach_dir = os.path.join(rtt_root, 'bsp', bsp, '.ci/attachconfig')
attach_list = []
#这里是旧的文件方式
for root, dirs, files in os.walk(attach_dir):
for file in files:
if file.endswith('attach'):