diff --git a/.github/ALL_BSP_COMPILE.json b/.github/ALL_BSP_COMPILE.json index 84f272d066f..cdeaf005e89 100644 --- a/.github/ALL_BSP_COMPILE.json +++ b/.github/ALL_BSP_COMPILE.json @@ -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", @@ -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" + ] } ] } diff --git a/.github/workflows/bsp_buildings.yml b/.github/workflows/bsp_buildings.yml index 0ea40addcb6..e664afc2c10 100644 --- a/.github/workflows/bsp_buildings.yml +++ b/.github/workflows/bsp_buildings.yml @@ -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: | diff --git a/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml b/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml index f25e65d7b6a..5b09b34d76e 100644 --- a/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml +++ b/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml @@ -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: @@ -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 diff --git a/tools/ci/bsp_buildings.py b/tools/ci/bsp_buildings.py index 8ba412a779d..6678b5cef58 100644 --- a/tools/ci/bsp_buildings.py +++ b/tools/ci/bsp_buildings.py @@ -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 @@ 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} ====") @@ -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.') @@ -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'):