Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/ALL_BSP_COMPILE.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -449,6 +448,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"
]
}
]
}
8 changes: 8 additions & 0 deletions .github/workflows/bsp_buildings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,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: |
Expand Down
45 changes: 40 additions & 5 deletions bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml
Original file line number Diff line number Diff line change
@@ -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.EMAC:
kconfig:
Expand All @@ -9,15 +20,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
127 changes: 119 additions & 8 deletions tools/ci/bsp_buildings.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.

Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -169,10 +220,12 @@ def build_bsp_attachconfig(bsp, attach_file):
"""
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} ====")
Expand Down Expand Up @@ -207,26 +260,80 @@ def build_bsp_attachconfig(bsp, attach_file):
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.')
Expand All @@ -235,11 +342,15 @@ def build_bsp_attachconfig(bsp, attach_file):
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'):
Expand Down