mirror of
https://github.com/apache/nuttx.git
synced 2026-08-02 12:49:00 +00:00
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 <raul_chen@realsil.com.cn>
This commit is contained in:
parent
54213a13b3
commit
84106b9152
7 changed files with 163 additions and 19 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
40
arch/arm/src/common/ameba/tools/ameba_asdk_version.sh
Executable file
40
arch/arm/src/common/ameba/tools/ameba_asdk_version.sh
Executable file
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue