This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 84106b915268fe9618714e0b8b3654a3b5977961 Author: raul_chen <[email protected]> AuthorDate: Thu Jul 16 18:04:31 2026 +0800 arch/arm/ameba: resolve the asdk toolchain per-IC Each ameba IC pins its asdk (arm-none-eabi) version in the SDK (component/soc/<soc>/project/CMakeLists.txt): RTL8720F needs 12.3.1 while RTL8721Dx needs 10.3.1. Both share the same arm-none-eabi triple and differ only by install directory. The make + cmake setup previously read only the global default, so the NuttX objects for an IC pinning a newer asdk were built with the wrong compiler (not the one its SDK archives were built with). Resolve the version per-IC from a single helper (ameba_asdk_version.sh, keyed by the SoC) used by every caller: - toolchain.mk / ameba_board.mk: make picks the right asdk automatically (it already knows the SoC), no user action. - ameba_fetch_toolchain.sh: fetches the version the SoC pins. - tools/ameba/env.sh: takes an optional board (`. tools/ameba/env.sh <board>`) so cmake, which locks the compiler at project() time, gets the matching asdk on PATH before it probes. No board -> the global default. - ameba_sdk.cmake: fail configure with a fix-it message if the on-PATH compiler is not the version this IC needs (e.g. a stale env from another board), instead of silently mis-compiling. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: raul_chen <[email protected]> --- arch/arm/src/common/ameba/cmake/ameba_sdk.cmake | 25 +++++++- arch/arm/src/common/ameba/toolchain.mk | 14 +++-- .../src/common/ameba/tools/ameba_asdk_version.sh | 40 ++++++++++++ .../common/ameba/tools/ameba_fetch_toolchain.sh | 27 +++++--- arch/arm/src/rtl8720f/ameba_board.mk | 2 +- arch/arm/src/rtl8721dx/ameba_board.mk | 2 +- tools/ameba/env.sh | 72 ++++++++++++++++++++-- 7 files changed, 163 insertions(+), 19 deletions(-) diff --git a/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake b/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake index b2121ccfc74..3c59e5baaea 100644 --- a/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake +++ b/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake @@ -60,5 +60,28 @@ if(NOT "${CMAKE_C_COMPILER}" MATCHES "${AMEBA_TOOLCHAIN_DIR}") FATAL_ERROR "C compiler '${CMAKE_C_COMPILER}' is not the ameba asdk toolchain.\n" "Source the build environment before configuring:\n" - " . tools/ameba/env.sh") + " . tools/ameba/env.sh ${CONFIG_ARCH_BOARD}") +endif() + +# ...and it must be the asdk version THIS IC pins (RTL8720F -> 12.3.1, RTL8721Dx +# -> 10.3.1). Both versions share the same arm-none-eabi triple and differ only +# by directory, so a PATH left over from another board (env.sh not re-sourced) +# would silently build NuttX with the wrong compiler. Catch it at configure +# time and say exactly how to fix it. +execute_process( + COMMAND sh ${_ameba_common_dir}/tools/ameba_asdk_version.sh ${AMEBA_SDK} + ${AMEBA_SOC_NAME} + OUTPUT_VARIABLE _ameba_want_ver + OUTPUT_STRIP_TRAILING_WHITESPACE) +if(_ameba_want_ver AND NOT "${CMAKE_C_COMPILER}" MATCHES + "asdk-${_ameba_want_ver}-") + message( + FATAL_ERROR + "compiler '${CMAKE_C_COMPILER}'\n" + " is not asdk-${_ameba_want_ver}, which ${CONFIG_ARCH_CHIP} requires. The " + "environment is likely still set for another board. Re-source it for " + "this board (a fresh build dir per board):\n" + " . tools/ameba/env.sh ${CONFIG_ARCH_BOARD}\n" + " cmake -B build-${CONFIG_ARCH_BOARD} -DBOARD_CONFIG=${CONFIG_ARCH_BOARD}:<config> -GNinja" + ) endif() diff --git a/arch/arm/src/common/ameba/toolchain.mk b/arch/arm/src/common/ameba/toolchain.mk index ba2b52dd715..e86871dd4d0 100644 --- a/arch/arm/src/common/ameba/toolchain.mk +++ b/arch/arm/src/common/ameba/toolchain.mk @@ -5,9 +5,15 @@ # SDK requires, by reading the SDK's own declaration -- the SDK is the single # source of truth, so the toolchain can never drift from the pinned SDK commit: # -# cmake/global_define.cmake -> v_ASDK_VER (10.3.1) +# component/soc/<soc>/project/CMakeLists.txt -> v_ASDK_VER (per-IC pin) +# cmake/global_define.cmake -> v_ASDK_VER (default) # cmake/toolchain/ameba-toolchain-asdk-<ver>.cmake -> ToolChainVerMinor (4602) # +# The version is resolved per-IC (ameba_asdk_version.sh, keyed by +# AMEBA_SOC_NAME) so a chip pinning a newer asdk -- e.g. RTL8720F -> 12.3.1 -- +# builds the NuttX objects with the SAME toolchain as its SDK archives, not the +# RTL8721Dx 10.3.1 default. +# # When the SDK is bumped to a commit that needs a different toolchain, those # cmake values change and this picks the new toolchain up automatically -- no # manual sync of a duplicated pin in the NuttX tree. Path layout mirrors the @@ -24,9 +30,9 @@ AMEBA_TOOLCHAIN_DIR ?= $(HOME)/rtk-toolchain -AMEBA_ASDK_VER := $(strip $(shell sed -n \ - 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \ - $(AMEBA_SDK)/cmake/global_define.cmake 2>/dev/null)) +AMEBA_ASDK_VER := $(strip $(shell sh \ + $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_asdk_version.sh \ + $(AMEBA_SDK) $(AMEBA_SOC_NAME) 2>/dev/null)) ifneq ($(AMEBA_ASDK_VER),) AMEBA_ASDK_BUILD := $(strip $(shell sed -n \ diff --git a/arch/arm/src/common/ameba/tools/ameba_asdk_version.sh b/arch/arm/src/common/ameba/tools/ameba_asdk_version.sh new file mode 100755 index 00000000000..c5f29136a2c --- /dev/null +++ b/arch/arm/src/common/ameba/tools/ameba_asdk_version.sh @@ -0,0 +1,40 @@ +#!/bin/sh +############################################################################ +# arch/arm/src/common/ameba/tools/ameba_asdk_version.sh +# +# Resolve the asdk (arm-none-eabi) toolchain VERSION the SDK requires for a +# given SoC, so the NuttX objects are built with the SAME toolchain the SDK +# archives they link against were built with. The SDK is the single source +# of truth and resolves the version per-SoC, in this order: +# +# 1. component/soc/<soc>/project/CMakeLists.txt -> set(v_ASDK_VER X) +# Per-IC override; e.g. RTL8720F / amebagreen2 pin 12.3.1. +# 2. cmake/global_define.cmake -> ameba_set_if_unset(v_ASDK_VER X) +# The default for SoCs without an override (e.g. RTL8721Dx -> 10.3.1). +# +# Usage: ameba_asdk_version.sh <sdk_dir> [soc_name] +# Prints the resolved version (e.g. "12.3.1") to stdout, nothing on failure. +# With no <soc_name> (or an unknown one) it returns the global default, which +# keeps the make/cmake callers backward compatible. +############################################################################ + +SDK="$1" +SOC="$2" + +[ -n "$SDK" ] || exit 0 + +ver= + +# 1. Per-SoC override, if this SoC pins its own version. +if [ -n "$SOC" ] && [ -f "$SDK/component/soc/$SOC/project/CMakeLists.txt" ]; then + ver=$(sed -n 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \ + "$SDK/component/soc/$SOC/project/CMakeLists.txt" | head -1) +fi + +# 2. Fall back to the global default. +if [ -z "$ver" ]; then + ver=$(sed -n 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \ + "$SDK/cmake/global_define.cmake" 2>/dev/null | head -1) +fi + +[ -n "$ver" ] && echo "$ver" diff --git a/arch/arm/src/common/ameba/tools/ameba_fetch_toolchain.sh b/arch/arm/src/common/ameba/tools/ameba_fetch_toolchain.sh index bc3a86b9ba5..dd95caca2aa 100755 --- a/arch/arm/src/common/ameba/tools/ameba_fetch_toolchain.sh +++ b/arch/arm/src/common/ameba/tools/ameba_fetch_toolchain.sh @@ -12,9 +12,11 @@ # tar -jxf $NAME -> $TOOLCHAIN_DIR/asdk-<ver> # rename asdk-<ver> -> asdk-<ver>-<build> # -# Usage: ameba_fetch_toolchain.sh <sdk_dir> [toolchain_dir] +# Usage: ameba_fetch_toolchain.sh <sdk_dir> [toolchain_dir] [soc_name] # <sdk_dir> ameba-rtos checkout (has cmake/global_define.cmake) # [toolchain_dir] install root (default: $HOME/rtk-toolchain) +# [soc_name] SDK soc dir (e.g. RTL8720F); selects the +# per-IC asdk version. Omitted -> the global default. # # No-op when the matching toolchain is already present, so it is safe to call # at the start of every build. @@ -24,16 +26,16 @@ set -e SDK="$1" TOOLCHAIN_DIR="${2:-$HOME/rtk-toolchain}" +SOC="$3" if [ -z "$SDK" ] || [ ! -f "$SDK/cmake/global_define.cmake" ]; then echo "ameba_fetch_toolchain.sh: bad SDK dir '$SDK'" >&2 exit 1 fi -# --- Read the pinned version from the SDK (the single source of truth) ------ +# --- Resolve the version this SoC pins (SDK is the single source of truth) -- -VER=$(sed -n 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \ - "$SDK/cmake/global_define.cmake") +VER=$(sh "$(dirname "$0")/ameba_asdk_version.sh" "$SDK" "$SOC") TC_CMAKE="$SDK/cmake/toolchain/ameba-toolchain-asdk-$VER.cmake" if [ -z "$VER" ] || [ ! -f "$TC_CMAKE" ]; then echo "ameba_fetch_toolchain.sh: cannot resolve ASDK version from SDK" >&2 @@ -49,9 +51,20 @@ if [ -x "$DEST/linux/newlib/bin/arm-none-eabi-gcc" ]; then exit 0 fi -# Archive name + candidate URLs, read from the SDK toolchain cmake. The cmake -# offers an Aliyun (default) and a GitHub (USE_SECOND_SOURCE) mirror; try both. -NAME="$MAJOR-linux-newlib-build-$BUILD-x86_64_with_small_reent.tar.bz2" +# Archive name + candidate URLs, read from the SDK toolchain cmake. The Linux +# TOOLCHAINNAME suffix differs by version (10.3.1 has _with_small_reent, 12.3.1 +# does not), so read it from the SDK rather than hard-coding, expanding the +# ${ToolChainVerMajor}/${ToolChainVerMinor} it references. The cmake offers an +# Aliyun (default) and a GitHub (USE_SECOND_SOURCE) mirror; try both. +NAME=$(sed -n \ + 's/.*set(TOOLCHAINNAME[ \t][ \t]*\([^ )]*x86_64[^ )]*\.tar\.bz2\).*/\1/p' \ + "$TC_CMAKE" | head -1) +NAME=$(echo "$NAME" | sed -e "s/\${ToolChainVerMajor}/$MAJOR/g" \ + -e "s/\${ToolChainVerMinor}/$BUILD/g") +if [ -z "$NAME" ]; then + echo "ameba_fetch_toolchain.sh: no Linux TOOLCHAINNAME found in $TC_CMAKE" >&2 + exit 1 +fi URLS=$(sed -n 's/.*set(TOOLCHAINURL[ \t][ \t]*\(http[^ )]*\).*/\1/p' "$TC_CMAKE") if [ -z "$URLS" ]; then echo "ameba_fetch_toolchain.sh: no TOOLCHAINURL found in $TC_CMAKE" >&2 diff --git a/arch/arm/src/rtl8720f/ameba_board.mk b/arch/arm/src/rtl8720f/ameba_board.mk index 4e03c3f059f..2d0413ac9a1 100644 --- a/arch/arm/src/rtl8720f/ameba_board.mk +++ b/arch/arm/src/rtl8720f/ameba_board.mk @@ -260,7 +260,7 @@ AMEBA_NP_POSTBUILD = AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ define PREBUILD $(Q) test -n "$(AMEBA_SDK)" || \ { echo "ERROR: AMEBA_SDK is not set. Export it to your ameba-rtos checkout."; exit 1; } - $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) + $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(AMEBA_SOC_NAME) $(Q) $(AMEBA_SETUP_ENV) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(Q) AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ diff --git a/arch/arm/src/rtl8721dx/ameba_board.mk b/arch/arm/src/rtl8721dx/ameba_board.mk index 13b80601e42..d3648dea965 100644 --- a/arch/arm/src/rtl8721dx/ameba_board.mk +++ b/arch/arm/src/rtl8721dx/ameba_board.mk @@ -260,7 +260,7 @@ AMEBA_NP_POSTBUILD = AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ define PREBUILD $(Q) test -n "$(AMEBA_SDK)" || \ { echo "ERROR: AMEBA_SDK is not set. Export it to your ameba-rtos checkout."; exit 1; } - $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) + $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(AMEBA_SOC_NAME) $(Q) $(AMEBA_SETUP_ENV) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(Q) AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ diff --git a/tools/ameba/env.sh b/tools/ameba/env.sh index fbf03051ddd..5a1097fbb0b 100755 --- a/tools/ameba/env.sh +++ b/tools/ameba/env.sh @@ -60,6 +60,43 @@ AMEBA_COMMON="$AMEBA_NUTTX/arch/arm/src/common/ameba" AMEBA_TOOLS="$AMEBA_COMMON/tools" AMEBA_TOOLCHAIN_DIR="${AMEBA_TOOLCHAIN_DIR:-$HOME/rtk-toolchain}" +# --- Optional target board: `. tools/ameba/env.sh <board>[:config]` ---------- +# CMake locks the compiler at project() time (before the board arch is +# processed), so the per-IC asdk toolchain must be on PATH *before* cmake. +# Passing the board here lets env.sh resolve its SoC and fetch/PATH the matching +# asdk version (e.g. rtl8720f_evb -> RTL8720F -> 12.3.1). With no argument the +# global default is used (correct for the RTL8721Dx boards, e.g. pke8721daf). + +# The boards this script knows: every board under an ameba arch chip (its arch +# CMakeLists declares AMEBA_SOC_NAME). Enumerated from the tree, so new ICs +# appear automatically. +_ameba_board_list() { + for _cml in "$AMEBA_NUTTX"/arch/arm/src/*/CMakeLists.txt; do + grep -q AMEBA_SOC_NAME "$_cml" 2>/dev/null || continue + _c=$(basename "$(dirname "$_cml")") + for _b in "$AMEBA_NUTTX"/boards/arm/"$_c"/*/; do + [ -d "$_b" ] && printf '%s ' "$(basename "$_b")" + done + done +} + +_ameba_board="${1%%:*}" +_ameba_soc= +if [ -n "$_ameba_board" ]; then + _ameba_bdir=$(cd "$AMEBA_NUTTX" 2>/dev/null && + ls -d boards/arm/*/"$_ameba_board" 2>/dev/null | head -1) + if [ -n "$_ameba_bdir" ]; then + _ameba_chip=$(basename "$(dirname "$AMEBA_NUTTX/$_ameba_bdir")") + _ameba_soc=$(sed -n \ + 's/.*set(AMEBA_SOC_NAME[ \t][ \t]*\([A-Za-z0-9_]*\).*/\1/p' \ + "$AMEBA_NUTTX/arch/arm/src/$_ameba_chip/CMakeLists.txt" 2>/dev/null | head -1) + else + echo "ameba env.sh: unknown board '$_ameba_board'." >&2 + echo " known ameba boards: $(_ameba_board_list)" >&2 + echo " continuing with the default asdk." >&2 + fi +fi + # --- 1. Resolve / fetch the SDK (pin comes from ameba_sdk.mk, single source) -- if [ -n "$AMEBA_SDK" ] && [ -d "$AMEBA_SDK/component/soc" ]; then @@ -79,11 +116,10 @@ export AMEBA_TOOLCHAIN_DIR # --- 2. asdk toolchain: fetch if absent, prepend to PATH, pin GCCVER --------- -sh "$AMEBA_TOOLS/ameba_fetch_toolchain.sh" "$AMEBA_SDK" "$AMEBA_TOOLCHAIN_DIR" \ +sh "$AMEBA_TOOLS/ameba_fetch_toolchain.sh" "$AMEBA_SDK" "$AMEBA_TOOLCHAIN_DIR" "$_ameba_soc" \ || return 1 2>/dev/null || exit 1 -_ver=$(sed -n 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \ - "$AMEBA_SDK/cmake/global_define.cmake") +_ver=$(sh "$AMEBA_TOOLS/ameba_asdk_version.sh" "$AMEBA_SDK" "$_ameba_soc") _build=$(sed -n 's/.*ToolChainVerMinor[ \t][ \t]*\([0-9][0-9]*\).*/\1/p' \ "$AMEBA_SDK/cmake/toolchain/ameba-toolchain-asdk-$_ver.cmake") _asdk_bin="$AMEBA_TOOLCHAIN_DIR/asdk-$_ver-$_build/linux/newlib/bin" @@ -98,8 +134,27 @@ _pbv=$(sed -n 's/^PREBUILTS_VERSION=//p' "$AMEBA_SDK/env.sh" | head -1) _prebuilts_bin="$AMEBA_TOOLCHAIN_DIR/prebuilts-linux-$_pbv/bin" _venv_bin="$(cat "$AMEBA_SDK/.amebapy/bindir" 2>/dev/null)" -# --- 4. Prepend to PATH (idempotent) ----------------------------------------- +# --- 4. Prepend to PATH ------------------------------------------------------ +# First strip any asdk bin from OUR toolchain dir already on PATH: re-sourcing +# for a different IC (e.g. RTL8720F 12.3.1 -> RTL8721Dx 10.3.1) must move THIS +# board's asdk to the front, but a plain "prepend if absent" would leave the +# previous version ahead and cmake's compiler probe would pick the wrong one. +# Anchored to $AMEBA_TOOLCHAIN_DIR so only our own asdk installs are touched -- +# never a system/third-party toolchain elsewhere on PATH. +_newpath= +_oldifs=$IFS +IFS=: +for _p in $PATH; do + case "$_p" in + "$AMEBA_TOOLCHAIN_DIR"/asdk-*/linux/newlib/bin) ;; # our stale asdk -- drop + *) _newpath="${_newpath:+$_newpath:}$_p" ;; + esac +done +IFS=$_oldifs +PATH="$_newpath" +# venv + prebuilts are version-independent, so prepend-if-absent is fine; the +# asdk bin was just stripped, so it is prepended here and lands at the front. for _d in "$_venv_bin" "$_prebuilts_bin" "$_asdk_bin"; do [ -n "$_d" ] || continue case ":$PATH:" in @@ -111,5 +166,12 @@ export PATH echo "ameba: environment ready" echo " AMEBA_SDK = $AMEBA_SDK" -echo " asdk = $_asdk_bin" +echo " asdk = $_asdk_bin (${_ameba_soc:-default}: $_ver)" +if [ -z "$_ameba_soc" ]; then + echo " note: no board given -> default asdk $_ver. For an IC that pins a" + echo " newer asdk (e.g. rtl8720f_evb), pass the board so cmake builds" + echo " NuttX with the matching toolchain:" + echo " . tools/ameba/env.sh <board>" + [ -z "$_ameba_board" ] && echo " boards: $(_ameba_board_list)" +fi echo " now build with cmake (source once) or make"
