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"

Reply via email to