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 541e9d13a2d4aea288ce52f1aef7ebe4af8bd76b
Author: raul_chen <[email protected]>
AuthorDate: Thu Jul 16 15:01:57 2026 +0800

    arch/arm/ameba: add CMake build support for RTL8721Dx and RTL8720F
    
    Both Ameba WHC boards (pke8721daf, rtl8720f_evb) previously built only via 
the
    make build; the board CMakeLists fell back to a FATAL_ERROR.  Wire up the 
full
    vendor-SDK machinery for CMake so `cmake --build` produces the same 
flashable
    nuttx.bin as make, with no change to any shared/arch-common file:
    
      - tools/ameba/env.sh: source it once before cmake.  It 
resolves/auto-fetches
        the ameba-rtos SDK + its pinned asdk toolchain (reusing the same helper
        scripts the make build uses) and puts the toolchain on PATH, so cmake's
        normal compiler probe finds it -- exactly like every other NuttX board's
        toolchain.  No per-chip hook is added to the shared arch 
Toolchain.cmake.
      - common/ameba/cmake/ameba_sdk.cmake: resolve AMEBA_SDK + asdk dir from 
that
        environment (fall back to the in-tree checkout) and sanity-check the
        compiler; included by each arch chip CMakeLists before its SDK-relative
        source lists.
      - common/ameba/cmake/ameba_board.cmake: the shared mechanism -- autoconf,
        libameba_fwlib.a / libameba_wifi.a compiled with the isolated SDK 
include
        set, the image2 linker script, the image2 link flags + EXTRA_LIBS, 
nuttx.bin
        packaging and the flash target.  Per-IC inputs are set by each arch chip
        CMakeLists.
      - common/ameba/tools/{ameba_gen_ldscript,ameba_package,ameba_flash}.sh:
        shared shell steps used by both the make and cmake paths so the two 
produce
        identical output; tools/ameba/Config.mk now flashes via ameba_flash.sh 
too.
      - Fix a latent rtl8720f CMakeLists source list bug (ameba_ipc.c was 
missing
        for the WiFi / flash-fs configs).
    
    The make build is unchanged (it still auto-fetches everything, so sourcing
    env.sh is optional there and required only for cmake).  Verified on 
hardware:
    both boards build, flash and boot with WiFi over the CMake path.
    
    Assisted-by: Claude Code:claude-opus-4-8
    Signed-off-by: raul_chen <[email protected]>
---
 .../arm/rtl8720f/boards/rtl8720f_evb/index.rst     |  48 +---
 Documentation/platforms/arm/rtl8720f/index.rst     | 101 +++++--
 .../arm/rtl8721dx/boards/pke8721daf/index.rst      |  48 +---
 Documentation/platforms/arm/rtl8721dx/index.rst    | 101 +++++--
 arch/arm/src/common/ameba/cmake/ameba_board.cmake  | 314 +++++++++++++++++++++
 arch/arm/src/common/ameba/cmake/ameba_sdk.cmake    |  64 +++++
 arch/arm/src/common/ameba/tools/ameba_fetch_sdk.sh |   5 +-
 arch/arm/src/common/ameba/tools/ameba_flash.sh     |  95 +++++++
 .../src/common/ameba/tools/ameba_gen_ldscript.sh   |  69 +++++
 arch/arm/src/common/ameba/tools/ameba_package.sh   | 164 +++++++++++
 arch/arm/src/rtl8720f/CMakeLists.txt               | 139 +++++++++
 arch/arm/src/rtl8721dx/CMakeLists.txt              | 133 +++++++++
 boards/arm/rtl8720f/rtl8720f_evb/CMakeLists.txt    |  16 +-
 .../arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt   |   3 +-
 boards/arm/rtl8721dx/pke8721daf/CMakeLists.txt     |  16 +-
 boards/arm/rtl8721dx/pke8721daf/src/CMakeLists.txt |   3 +-
 tools/ameba/Config.mk                              |  73 +----
 tools/ameba/env.sh                                 | 115 ++++++++
 18 files changed, 1296 insertions(+), 211 deletions(-)

diff --git a/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst 
b/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst
index 7d27c83d0ea..aa5351d93fe 100644
--- a/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst
+++ b/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst
@@ -40,6 +40,10 @@ This NuttX port does not wire any user buttons or LEDs.
 Configurations
 ==============
 
+Build and flash any of these per the :doc:`RTL8720F build instructions
+<../../index>`; for the CMake build, source ``. tools/ameba/env.sh
+rtl8720f_evb`` first (the make build needs no sourcing).
+
 .. code:: console
 
    $ ./tools/configure.sh rtl8720f_evb:<config-name>
@@ -71,50 +75,6 @@ SoftAP (become an access point, with a DHCP server for 
clients)::
 
 Stop the SoftAP with ``wapi essid wlan0 <ssid> 0``.
 
-Building and Flashing
-=====================
-
-The build auto-fetches the Realtek ``ameba-rtos`` SDK on first use and a
-Realtek ``arm-none-eabi`` toolchain must be on ``PATH``; see the
-:doc:`chip documentation <../../index>` for both.
-
-.. code:: console
-
-   $ ./tools/configure.sh rtl8720f_evb:nsh
-   $ make
-
-This produces ``nuttx.bin`` in the top-level build directory: the NuttX
-application image, which also bundles the prebuilt Wi-Fi firmware.  The
-bootloader ``boot.bin`` is a prebuilt binary kept under the board's
-``prebuilt/`` directory; ``make flash`` writes both at the flash offsets
-taken from the generated flash layout, so no offsets are entered by hand.
-
-After a successful build, flash via one of these methods:
-
-**CLI (Linux/macOS)** — connect a USB-UART adapter (PL2303) and use the
-built-in ``make flash`` target:
-
-.. code:: console
-
-   $ make flash AMEBA_PORT=/dev/ttyUSB0
-
-The baud rate defaults to 1500000; override with ``AMEBA_BAUD`` if needed.
-
-**GUI (Windows)** — use the Realtek AmebaImageTool (``AmebaImageTool.exe``
-under ``tools/ameba/ImageTool/`` in the SDK tree) to select ``boot.bin`` (from
-the board's ``prebuilt/`` directory) and ``nuttx.bin``.
-
-See the `Realtek Ameba ImageTool guide
-<https://aiot.realmcu.com/en/latest/tools/image_tool/index.html>`_ for the
-Windows GUI tool and download-mode entry (hold the download button /
-power-cycle with the ``UART_LOG_TX`` line asserted).
-
-**Serial console** — after flashing, connect to the LOG-UART at 1500000 8N1::
-
-    $ picocom -b 1500000 /dev/ttyUSB0
-
-Other tools: ``screen /dev/ttyUSB0 1500000`` or ``minicom -b 1500000 -D 
/dev/ttyUSB0``.
-
 License Exceptions
 ==================
 
diff --git a/Documentation/platforms/arm/rtl8720f/index.rst 
b/Documentation/platforms/arm/rtl8720f/index.rst
index ecdb78c0701..bd34c923f0e 100644
--- a/Documentation/platforms/arm/rtl8720f/index.rst
+++ b/Documentation/platforms/arm/rtl8720f/index.rst
@@ -40,24 +40,93 @@ NOR accessed through the SDK XIP path. The exact flash / 
PSRAM size depends on
 the part number — for example the RTL8720FBF has 4 MB of NOR flash and no
 PSRAM.
 
-Vendor SDK Dependency
+Vendor SDK and Toolchain
+========================
+
+The build depends on Realtek's open ``ameba-rtos`` SDK and its matching
+``arm-none-eabi`` toolchain (from the Realtek asdk release), neither of which 
is
+part of the NuttX tree.  The SDK provides the Wi-Fi / Bluetooth firmware and 
the
+low-level chip libraries; NuttX links its own libc / libm and reuses the SDK's
+``app_start()`` as the image entry point.
+
+Both are fetched automatically — there is nothing to install by hand:
+
+- **make** fetches them on the first ``make`` (from its ``PREBUILD`` step).
+- **CMake** fetches them when you source ``. tools/ameba/env.sh <board>``, 
which
+  must run before ``cmake`` (CMake probes the compiler at configure time).  The
+  make build resolves everything on demand, so it needs no sourcing.
+
+The SDK is a shallow ``git clone`` of the pinned revision of
+``https://github.com/Ameba-AIoT/ameba-rtos.git`` into
+``arch/arm/src/common/ameba/ameba-rtos`` (git-ignored) and is built unmodified;
+export ``AMEBA_SDK`` to use a local checkout instead.  The asdk version is
+pinned **per IC** by the SDK, so different Ameba ICs may use different 
toolchain
+versions — the build selects the matching one automatically.
+
+Building and Flashing
 =====================
 
-The build depends on Realtek's open ``ameba-rtos`` SDK, which is **not** part
-of the NuttX tree. It provides the Wi-Fi / Bluetooth firmware and the
-low-level chip libraries. The first build auto-fetches the pinned revision (a
-shallow ``git clone`` of ``https://github.com/Ameba-AIoT/ameba-rtos.git``) into
-``arch/arm/src/common/ameba/ameba-rtos`` (git-ignored) and builds against it
-unmodified. To use a local checkout instead of auto-fetching, export
-``AMEBA_SDK`` to its path.
-
-Toolchain
-=========
-
-A matching Realtek ARM toolchain (``arm-none-eabi`` from the Realtek asdk
-release) is required and is fetched automatically by the board build. NuttX
-links its own libc / libm and reuses the SDK's ``app_start()`` as the image
-entry point.
+Replace ``<board>`` below with an actual board (e.g. ``rtl8720f_evb``) and
+``<config>`` with one of its configurations.  The first build fetches the SDK
+and toolchain (see `Vendor SDK and Toolchain`_).
+
+With make
+---------
+
+.. code:: console
+
+   $ ./tools/configure.sh <board>:<config>
+   $ make
+
+With CMake
+----------
+
+CMake probes the compiler at configure time, so source the Ameba environment
+once first, **passing the board** so the asdk version that IC pins is on
+``PATH``:
+
+.. code:: console
+
+   $ . tools/ameba/env.sh <board>
+   $ cmake -B build -DBOARD_CONFIG=<board>:<config> -GNinja
+   $ cmake --build build
+
+make writes ``nuttx.bin`` to the top-level directory; CMake writes it under
+``build/``.  The bootloader ``boot.bin`` is a prebuilt binary under the board's
+``prebuilt/`` directory; the flash step writes both at the offsets taken from
+the generated flash layout, so none are entered by hand.
+
+Flashing
+--------
+
+**CLI (Linux/macOS)** — connect a USB-UART adapter and use the built-in flash
+target (the baud defaults to 1500000; override with ``AMEBA_BAUD``)::
+
+  $ make flash AMEBA_PORT=/dev/ttyUSB0                            # make build
+  $ AMEBA_PORT=/dev/ttyUSB0 cmake --build build --target flash    # CMake build
+
+**GUI (Windows)** — use the Realtek AmebaImageTool (``AmebaImageTool.exe`` 
under
+``tools/ameba/ImageTool/`` in the SDK tree) to select ``boot.bin`` (from the
+board's ``prebuilt/`` directory) and ``nuttx.bin``.  See the `Realtek Ameba
+ImageTool guide 
<https://aiot.realmcu.com/en/latest/tools/image_tool/index.html>`_
+for the Windows GUI tool and download-mode entry (hold the download button /
+power-cycle with the ``UART_LOG_TX`` line asserted).
+
+**Serial console** — after flashing, connect to the LOG-UART at 1500000 8N1::
+
+  $ picocom -b 1500000 /dev/ttyUSB0
+
+Configuration
+=============
+
+The build-time options are the same for make and CMake (both edit the one
+Kconfig for the selected board); only the command that launches the menuconfig
+UI differs:
+
+.. code:: console
+
+   $ make menuconfig                       # make build
+   $ cmake --build build -t menuconfig     # CMake build
 
 Supported Features
 ==================
diff --git a/Documentation/platforms/arm/rtl8721dx/boards/pke8721daf/index.rst 
b/Documentation/platforms/arm/rtl8721dx/boards/pke8721daf/index.rst
index 5d095dff244..e0e317b445b 100644
--- a/Documentation/platforms/arm/rtl8721dx/boards/pke8721daf/index.rst
+++ b/Documentation/platforms/arm/rtl8721dx/boards/pke8721daf/index.rst
@@ -42,6 +42,10 @@ This NuttX port does not wire any user buttons or LEDs.
 Configurations
 ==============
 
+Build and flash any of these per the :doc:`RTL8721Dx build instructions
+<../../index>`; for the CMake build, source ``. tools/ameba/env.sh
+pke8721daf`` first (the make build needs no sourcing).
+
 .. code:: console
 
    $ ./tools/configure.sh pke8721daf:<config-name>
@@ -73,50 +77,6 @@ SoftAP (become an access point, with a DHCP server for 
clients)::
 
 Stop the SoftAP with ``wapi essid wlan0 <ssid> 0``.
 
-Building and Flashing
-=====================
-
-The build auto-fetches the Realtek ``ameba-rtos`` SDK on first use and a
-Realtek ``arm-none-eabi`` toolchain must be on ``PATH``; see the
-:doc:`chip documentation <../../index>` for both.
-
-.. code:: console
-
-   $ ./tools/configure.sh pke8721daf:nsh
-   $ make
-
-This produces ``nuttx.bin`` in the top-level build directory: the NuttX
-application image, which also bundles the prebuilt Wi-Fi firmware.  The
-bootloader ``boot.bin`` is a prebuilt binary kept under the board's
-``prebuilt/`` directory; ``make flash`` writes both at the flash offsets
-taken from the generated flash layout, so no offsets are entered by hand.
-
-After a successful build, flash via one of these methods:
-
-**CLI (Linux/macOS)** — connect a USB-UART adapter (PL2303) and use the
-built-in ``make flash`` target:
-
-.. code:: console
-
-   $ make flash AMEBA_PORT=/dev/ttyUSB0
-
-The baud rate defaults to 1500000; override with ``AMEBA_BAUD`` if needed.
-
-**GUI (Windows)** — use the Realtek AmebaImageTool (``AmebaImageTool.exe``
-under ``tools/ameba/ImageTool/`` in the SDK tree) to select ``boot.bin`` (from
-the board's ``prebuilt/`` directory) and ``nuttx.bin``.
-
-See the `Realtek Ameba ImageTool guide
-<https://aiot.realmcu.com/en/latest/tools/image_tool/index.html>`_ for the
-Windows GUI tool and download-mode entry (hold the download button /
-power-cycle with the ``UART_LOG_TX`` line asserted).
-
-**Serial console** — after flashing, connect to the LOG-UART at 1500000 8N1::
-
-    $ picocom -b 1500000 /dev/ttyUSB0
-
-Other tools: ``screen /dev/ttyUSB0 1500000`` or ``minicom -b 1500000 -D 
/dev/ttyUSB0``.
-
 License Exceptions
 ==================
 
diff --git a/Documentation/platforms/arm/rtl8721dx/index.rst 
b/Documentation/platforms/arm/rtl8721dx/index.rst
index de21678350a..b29a620fc18 100644
--- a/Documentation/platforms/arm/rtl8721dx/index.rst
+++ b/Documentation/platforms/arm/rtl8721dx/index.rst
@@ -41,24 +41,93 @@ NOR accessed through the SDK XIP path. The exact flash / 
PSRAM size depends on
 the part number — for example the RTL8721DAF has 4 MB of NOR flash and no
 PSRAM.
 
-Vendor SDK Dependency
+Vendor SDK and Toolchain
+========================
+
+The build depends on Realtek's open ``ameba-rtos`` SDK and its matching
+``arm-none-eabi`` toolchain (from the Realtek asdk release), neither of which 
is
+part of the NuttX tree.  The SDK provides the Wi-Fi / Bluetooth firmware and 
the
+low-level chip libraries; NuttX links its own libc / libm and reuses the SDK's
+``app_start()`` as the image entry point.
+
+Both are fetched automatically — there is nothing to install by hand:
+
+- **make** fetches them on the first ``make`` (from its ``PREBUILD`` step).
+- **CMake** fetches them when you source ``. tools/ameba/env.sh <board>``, 
which
+  must run before ``cmake`` (CMake probes the compiler at configure time).  The
+  make build resolves everything on demand, so it needs no sourcing.
+
+The SDK is a shallow ``git clone`` of the pinned revision of
+``https://github.com/Ameba-AIoT/ameba-rtos.git`` into
+``arch/arm/src/common/ameba/ameba-rtos`` (git-ignored) and is built unmodified;
+export ``AMEBA_SDK`` to use a local checkout instead.  The asdk version is
+pinned **per IC** by the SDK, so different Ameba ICs may use different 
toolchain
+versions — the build selects the matching one automatically.
+
+Building and Flashing
 =====================
 
-The build depends on Realtek's open ``ameba-rtos`` SDK, which is **not** part
-of the NuttX tree. It provides the Wi-Fi / Bluetooth firmware and the
-low-level chip libraries. The first build auto-fetches the pinned revision (a
-shallow ``git clone`` of ``https://github.com/Ameba-AIoT/ameba-rtos.git``) into
-``arch/arm/src/common/ameba/ameba-rtos`` (git-ignored) and builds against it
-unmodified. To use a local checkout instead of auto-fetching, export
-``AMEBA_SDK`` to its path.
-
-Toolchain
-=========
-
-A matching Realtek ARM toolchain (``arm-none-eabi`` from the Realtek asdk
-release) is required and is fetched automatically by the board build. NuttX
-links its own libc / libm and reuses the SDK's ``app_start()`` as the image
-entry point.
+Replace ``<board>`` below with an actual board (e.g. ``pke8721daf``) and
+``<config>`` with one of its configurations.  The first build fetches the SDK
+and toolchain (see `Vendor SDK and Toolchain`_).
+
+With make
+---------
+
+.. code:: console
+
+   $ ./tools/configure.sh <board>:<config>
+   $ make
+
+With CMake
+----------
+
+CMake probes the compiler at configure time, so source the Ameba environment
+once first, **passing the board** so the asdk version that IC pins is on
+``PATH``:
+
+.. code:: console
+
+   $ . tools/ameba/env.sh <board>
+   $ cmake -B build -DBOARD_CONFIG=<board>:<config> -GNinja
+   $ cmake --build build
+
+make writes ``nuttx.bin`` to the top-level directory; CMake writes it under
+``build/``.  The bootloader ``boot.bin`` is a prebuilt binary under the board's
+``prebuilt/`` directory; the flash step writes both at the offsets taken from
+the generated flash layout, so none are entered by hand.
+
+Flashing
+--------
+
+**CLI (Linux/macOS)** — connect a USB-UART adapter and use the built-in flash
+target (the baud defaults to 1500000; override with ``AMEBA_BAUD``)::
+
+  $ make flash AMEBA_PORT=/dev/ttyUSB0                            # make build
+  $ AMEBA_PORT=/dev/ttyUSB0 cmake --build build --target flash    # CMake build
+
+**GUI (Windows)** — use the Realtek AmebaImageTool (``AmebaImageTool.exe`` 
under
+``tools/ameba/ImageTool/`` in the SDK tree) to select ``boot.bin`` (from the
+board's ``prebuilt/`` directory) and ``nuttx.bin``.  See the `Realtek Ameba
+ImageTool guide 
<https://aiot.realmcu.com/en/latest/tools/image_tool/index.html>`_
+for the Windows GUI tool and download-mode entry (hold the download button /
+power-cycle with the ``UART_LOG_TX`` line asserted).
+
+**Serial console** — after flashing, connect to the LOG-UART at 1500000 8N1::
+
+  $ picocom -b 1500000 /dev/ttyUSB0
+
+Configuration
+=============
+
+The build-time options are the same for make and CMake (both edit the one
+Kconfig for the selected board); only the command that launches the menuconfig
+UI differs:
+
+.. code:: console
+
+   $ make menuconfig                       # make build
+   $ cmake --build build -t menuconfig     # CMake build
 
 Supported Features
 ==================
diff --git a/arch/arm/src/common/ameba/cmake/ameba_board.cmake 
b/arch/arm/src/common/ameba/cmake/ameba_board.cmake
new file mode 100644
index 00000000000..cd0f8efed6d
--- /dev/null
+++ b/arch/arm/src/common/ameba/cmake/ameba_board.cmake
@@ -0,0 +1,314 @@
+# 
##############################################################################
+# arch/arm/src/common/ameba/cmake/ameba_board.cmake
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# 
##############################################################################
+
+# CMake counterpart of the make-side arch/.../<ic>/ameba_board.mk: the shared
+# vendor-SDK build machinery for every Ameba IC.  The per-IC arch 
CMakeLists.txt
+# sets the differing inputs (SoC subdir, source/include lists, AP project name)
+# then include()s this file, exactly as each board's scripts/Make.defs
+# include()s ameba_board.mk.  Every mechanism below mirrors a section of
+# ameba_board.mk; see that file for the detailed rationale and for the inputs
+# each arch chip CMakeLists.txt is expected to set.
+
+set(AMEBA_COMMON_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
+set(AMEBA_TOOLS_DIR ${AMEBA_COMMON_DIR}/tools)
+
+# AMEBA_SDK / AMEBA_TOOLCHAIN_DIR are resolved (and the compiler 
sanity-checked)
+# by ameba_sdk.cmake, which the arch chip CMakeLists includes before its
+# SDK-relative source lists; include it here too (no-op if already done) so 
this
+# file is self-contained.
+include(${CMAKE_CURRENT_LIST_DIR}/ameba_sdk.cmake)
+
+# The IC arch chip dir (the includer's dir) holds IC-specific sources such as
+# ameba_app_start.c, referenced by AMEBA_FWLIB_SRCS via ${AMEBA_CHIP_DIR}.
+set(AMEBA_CHIP_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+# SDK sub-trees + the board-local (gitignored) staging area, mirroring the make
+# variables of the same name.  Generated artefacts (autoconf, the two .a, the
+# combined ld script) go under the board prebuilt/ dir, shared with the make
+# build's staging.
+set(AMEBA_SOC ${AMEBA_SDK}/component/soc/${AMEBA_SOC_NAME})
+set(AMEBA_PROJ ${AMEBA_SOC}/project)
+set(AMEBA_KM4_PROJ ${AMEBA_PROJ}/${AMEBA_KM_PROJ})
+set(AMEBA_SOC_LIB ${AMEBA_KM4_PROJ}/lib/soc)
+
+set(AMEBA_PREBUILT ${NUTTX_BOARD_DIR}/prebuilt)
+set(AMEBA_PREBUILT_LIBS ${AMEBA_PREBUILT}/libs)
+set(AMEBA_AUTOCONF ${AMEBA_PREBUILT}/platform_autoconf.h)
+
+file(MAKE_DIRECTORY ${AMEBA_PREBUILT_LIBS})
+
+# ----------------------------------------------------------------------------
+# #3 platform_autoconf.h -- regenerated from the SDK menuconfig (single source
+# of truth for the flash layout + feature switches).  Done at CONFIGURE time so
+# the VFS1 geometry can be read back and injected into ameba_flash_mtd.c, and 
so
+# it exists before the ld-script preprocess / WiFi force-include below.
+# ----------------------------------------------------------------------------
+
+# Provision the SDK dev environment (prebuilts + python venv) the autoconf /
+# packaging steps need -- idempotent, mirrors the make PREBUILD's setup call.
+execute_process(COMMAND sh ${AMEBA_TOOLS_DIR}/ameba_setup_env.sh ${AMEBA_SDK}
+                        ${AMEBA_TOOLCHAIN_DIR} RESULT_VARIABLE _rc)
+if(NOT _rc EQUAL 0)
+  message(FATAL_ERROR "ameba_setup_env.sh failed (rc=${_rc})")
+endif()
+
+message(STATUS "ameba: generating platform_autoconf.h from SDK menuconfig")
+execute_process(
+  COMMAND sh ${AMEBA_TOOLS_DIR}/ameba_gen_autoconf.sh ${AMEBA_SDK}
+          ${AMEBA_PY_SOC} ${AMEBA_AP_PROJECT} ${AMEBA_AUTOCONF}
+  RESULT_VARIABLE _rc)
+if(NOT _rc EQUAL 0)
+  message(FATAL_ERROR "ameba_gen_autoconf.sh failed (rc=${_rc})")
+endif()
+
+# VFS1 data-partition geometry -> neutral -D macros on ameba_flash_mtd.c only 
(a
+# NuttX C file must not force-include the SDK autoconf).  Mirrors the make
+# CFLAGS derivation.  ameba_flash_mtd.c falls back to the vendor default if
+# absent.
+if(AMEBA_CFG_FLASHFS AND EXISTS ${AMEBA_AUTOCONF})
+  file(STRINGS ${AMEBA_AUTOCONF} _l REGEX "CONFIG_FLASH_VFS1_OFFSET")
+  if(_l)
+    list(GET _l 0 _l0)
+    string(REGEX REPLACE ".*CONFIG_FLASH_VFS1_OFFSET[ \t]+([0-9xXa-fA-F]+).*"
+                         "\\1" _vfs1_off "${_l0}")
+  endif()
+  file(STRINGS ${AMEBA_AUTOCONF} _l REGEX "CONFIG_FLASH_VFS1_SIZE")
+  if(_l)
+    list(GET _l 0 _l0)
+    string(REGEX REPLACE ".*CONFIG_FLASH_VFS1_SIZE[ \t]+([0-9xXa-fA-F]+).*"
+                         "\\1" _vfs1_size "${_l0}")
+  endif()
+  set(_flash_defs)
+  if(_vfs1_off)
+    list(APPEND _flash_defs AMEBA_FLASH_VFS1_OFFSET_XIP=${_vfs1_off})
+  endif()
+  if(_vfs1_size)
+    list(APPEND _flash_defs AMEBA_FLASH_VFS1_SIZE_CFG=${_vfs1_size})
+  endif()
+  if(_flash_defs)
+    set_property(
+      SOURCE ${AMEBA_COMMON_DIR}/ameba_flash_mtd.c
+      APPEND
+      PROPERTY COMPILE_DEFINITIONS ${_flash_defs})
+  endif()
+endif()
+
+# ----------------------------------------------------------------------------
+# #4 libameba_fwlib.a / libameba_wifi.a
+#
+# Compiled from SDK source with an ISOLATED flag+include set (the SDK headers
+# clash with NuttX's), so -- exactly like the make PREBUILD -- each source is
+# compiled by a bare custom-command invocation using NUTTX_EXTRA_FLAGS (the
+# toolchain cpu/opt flags, WITHOUT NuttX's include dirs) plus the SDK include
+# set, then archived.  add_library() is deliberately NOT used: it would inherit
+# the directory's NuttX include_directories() and pull in clashing headers.
+# ----------------------------------------------------------------------------
+
+# ~~~
+# ameba_build_lib(<lib_path> <obj_subdir> <srcs-var> <inc-var>)
+#   Compile each source in <srcs-var> to an object under <obj_subdir> with the
+#   isolated flags, then archive them all into <lib_path>.  Returns via the
+#   caller-supplied variable the target name to depend on.
+# ~~~
+function(ameba_build_lib lib obj_subdir srcs_var inc_var out_target)
+  set(_objdir ${AMEBA_PREBUILT_LIBS}/${obj_subdir})
+  file(MAKE_DIRECTORY ${_objdir})
+  set(_objs)
+  foreach(_src ${${srcs_var}})
+    get_filename_component(_base ${_src} NAME_WE)
+    set(_obj ${_objdir}/${_base}.o)
+    add_custom_command(
+      OUTPUT ${_obj}
+      COMMAND ${CMAKE_C_COMPILER} ${NUTTX_EXTRA_FLAGS} -Os -ffunction-sections
+              -fdata-sections ${${inc_var}} -c ${_src} -o ${_obj}
+      DEPENDS ${_src} ${AMEBA_AUTOCONF}
+      COMMAND_EXPAND_LISTS
+      COMMENT "CC (ameba ${obj_subdir}) ${_base}.o")
+    list(APPEND _objs ${_obj})
+  endforeach()
+  add_custom_command(
+    OUTPUT ${lib}
+    COMMAND ${CMAKE_AR} crs ${lib} ${_objs}
+    DEPENDS ${_objs}
+    COMMENT "AR ${lib}")
+  get_filename_component(_libname ${lib} NAME_WE)
+  add_custom_target(${_libname}_target DEPENDS ${lib})
+  set(${out_target}
+      ${_libname}_target
+      PARENT_SCOPE)
+endfunction()
+
+set(AMEBA_FWLIB_A ${AMEBA_PREBUILT_LIBS}/libameba_fwlib.a)
+ameba_build_lib(${AMEBA_FWLIB_A} fwlib_obj AMEBA_FWLIB_SRCS AMEBA_FWLIB_INC
+                _fwlib_target)
+add_dependencies(nuttx ${_fwlib_target})
+
+set(AMEBA_EXTRA_LIBS ${AMEBA_FWLIB_A})
+
+# chipinfo / pmc ship pre-compiled inside the SDK source tree.
+list(APPEND AMEBA_EXTRA_LIBS ${AMEBA_SOC_LIB}/lib_chipinfo.a
+     ${AMEBA_SOC_LIB}/lib_pmc.a)
+
+if(AMEBA_CFG_WIFI)
+  set(AMEBA_WIFI_A ${AMEBA_PREBUILT_LIBS}/libameba_wifi.a)
+  ameba_build_lib(${AMEBA_WIFI_A} wifi_obj AMEBA_WIFI_SRCS AMEBA_WIFI_INC
+                  _wifi_target)
+  add_dependencies(nuttx ${_wifi_target})
+
+  # KM4-side host WiFi control libs from the pinned SDK.  The exact set is
+  # IC-specific (e.g. lib_coex is an AP-side lib on RTL8721Dx but NP-side on
+  # RTL8720F), so the arch chip CMakeLists provides it via AMEBA_WIFI_APP_LIBS.
+  list(APPEND AMEBA_EXTRA_LIBS ${AMEBA_WIFI_APP_LIBS} ${AMEBA_WIFI_A})
+endif()
+
+# crtbegin.o / crtend.o (asdk gcc runtime) -- positional objects appended 
inside
+# the link group; -lm / -lstdc++ name-spec libs (C++ static-init + math).  The
+# cpu flags MUST be passed so gcc returns the multilib-correct crt objects (the
+# hard-float / cortex-m33 variant), else the link fails on a VFP/arch mismatch.
+execute_process(
+  COMMAND ${CMAKE_C_COMPILER} ${NUTTX_EXTRA_FLAGS} -print-file-name=crtbegin.o
+  OUTPUT_VARIABLE _crtbegin
+  OUTPUT_STRIP_TRAILING_WHITESPACE)
+execute_process(
+  COMMAND ${CMAKE_C_COMPILER} ${NUTTX_EXTRA_FLAGS} -print-file-name=crtend.o
+  OUTPUT_VARIABLE _crtend
+  OUTPUT_STRIP_TRAILING_WHITESPACE)
+list(APPEND AMEBA_EXTRA_LIBS ${_crtbegin} ${_crtend} -lm -lstdc++)
+
+# ----------------------------------------------------------------------------
+# #5 ld.script.gen -- combined image2 linker script (see 
ameba_gen_ldscript.sh).
+#
+# Generated at CONFIGURE time (like the autoconf above), NOT via a build-time
+# custom command: the top-level CMakeLists consumes LD_SCRIPT to build its cpp
+# ".tmp" preprocessing target in a different directory scope, and the Makefiles
+# generator cannot resolve a cross-directory add_custom_command OUTPUT as that
+# target's dependency ("No rule to make target ld.script.gen").  Producing it 
as
+# a real file up front sidesteps that -- its inputs (the SDK ld sources + the
+# config-derived autoconf) are all already present at configure time.
+# ----------------------------------------------------------------------------
+
+set(AMEBA_KM4_LD ${AMEBA_KM4_PROJ}/ld)
+set(AMEBA_IMG2_LD ${AMEBA_KM4_LD}/ameba_img2_all.ld)
+set(AMEBA_ROM_LD ${AMEBA_KM4_LD}/ameba_rom_symbol_acut_s.ld)
+set(GENLDSCRIPT ${AMEBA_PREBUILT}/ld.script.gen)
+
+message(
+  STATUS "ameba: generating ld.script.gen (AP ${AMEBA_AP_PROJECT} image2)")
+execute_process(
+  COMMAND
+    sh ${AMEBA_TOOLS_DIR}/ameba_gen_ldscript.sh ${CMAKE_C_COMPILER}
+    ${AMEBA_IMG2_LD} ${AMEBA_ROM_LD} ${AMEBA_AUTOCONF} ${AMEBA_PREBUILT}
+    ${AMEBA_AP_PROJECT} ${GENLDSCRIPT}
+  RESULT_VARIABLE _rc)
+if(NOT _rc EQUAL 0)
+  message(FATAL_ERROR "ameba_gen_ldscript.sh failed (rc=${_rc})")
+endif()
+
+set_property(GLOBAL PROPERTY LD_SCRIPT ${GENLDSCRIPT})
+
+# ----------------------------------------------------------------------------
+# #6 Link flags + EXTRA_LIBS (reproducing link_img2.sh).  The libs are appended
+# to the `nuttx` target so they land inside the top-level --start-group/
+# --end-group, resolving against each other and the NuttX libs; --gc-sections
+# drops everything unreferenced.
+# ----------------------------------------------------------------------------
+
+target_link_options(
+  nuttx
+  PRIVATE
+  -Wl,-u,app_start
+  -Wl,-e,app_start
+  -Wl,--gc-sections
+  -Wl,--no-enum-size-warning
+  -Wl,--warn-common
+  -Wl,--build-id=none
+  -Wl,--cref
+  -Wl,--defsym=_sbss=__bss_start__
+  -Wl,--defsym=_ebss=__bss_end__
+  -Wl,--defsym=_sdata=__sram_image2_start__
+  -Wl,--defsym=_edata=__sram_image2_start__
+  -Wl,--defsym=_eronly=__sram_image2_start__
+  -Wl,-Map=${CMAKE_BINARY_DIR}/nuttx.map
+  ${AMEBA_EXTRA_LINK_OPTIONS})
+
+# Append to NUTTX_EXTRA_LIBRARIES (not target_link_libraries): the top-level
+# link places this property INSIDE the --start-group/--end-group, so the SDK
+# archives resolve against each other and the NuttX libs.  A plain
+# target_link_libraries here would land them before the group and leave the
+# cross-references (FLASH_*, IPC_*, ameba_wifi_*) undefined.
+set_property(GLOBAL APPEND PROPERTY NUTTX_EXTRA_LIBRARIES ${AMEBA_EXTRA_LIBS})
+
+# ----------------------------------------------------------------------------
+# #7 POSTBUILD -- package the linked image2 into a flashable nuttx.bin. Wired
+# here (shared) so both boards on this IC get it; the whole recipe lives in
+# ameba_package.sh, invoked after `nuttx` is linked.
+# ----------------------------------------------------------------------------
+
+if(EXISTS ${AMEBA_TOOLS_DIR}/ameba_package.sh)
+  add_custom_target(
+    nuttx_post_build
+    DEPENDS nuttx
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+    COMMENT "PACK nuttx.bin (Ameba AP + NP image2)")
+  add_custom_command(
+    TARGET nuttx_post_build
+    POST_BUILD
+    COMMAND
+      ${CMAKE_COMMAND} -E env
+      "AMEBA_FLASH_HINT=AMEBA_PORT=/dev/ttyUSB0 cmake --build 
${CMAKE_BINARY_DIR} --target flash"
+      sh ${AMEBA_TOOLS_DIR}/ameba_package.sh ${AMEBA_SDK} ${AMEBA_PY_SOC}
+      ${AMEBA_SOC_NAME} ${AMEBA_PREBUILT} ${AMEBA_AP_PROJECT} ${AMEBA_KM_PROJ}
+      ${AMEBA_NP_TARGET} ${AMEBA_TOOLCHAIN_DIR} ${CMAKE_BINARY_DIR}/nuttx
+      ${CMAKE_BINARY_DIR}/nuttx.bin
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+    # USES_TERMINAL -> Ninja "console" pool: stream the (long) SDK NP-build +
+    # packaging output live instead of buffering it until the step finishes.
+    USES_TERMINAL COMMAND_EXPAND_LISTS)
+endif()
+
+# ----------------------------------------------------------------------------
+# `flash` target -- download boot.bin + nuttx.bin over serial (shared script).
+# The serial port + baud come from the environment at build time, so no
+# reconfigure is needed: AMEBA_PORT=/dev/ttyUSB0 [AMEBA_BAUD=1500000] cmake
+# --build <dir> --target flash AMEBA_FLASH_PROFILE names the SDK .rdev
+# flash-loader profile for this IC.
+# ----------------------------------------------------------------------------
+
+# The SDK flash-loader profile base name matches the public SoC id on both ICs
+# (RTL8721Dx.rdev / RTL8720F.rdev); default to it unless the arch overrides.
+if(NOT DEFINED AMEBA_FLASH_PROFILE)
+  set(AMEBA_FLASH_PROFILE ${AMEBA_PY_SOC})
+endif()
+
+if(AMEBA_FLASH_PROFILE AND NOT TARGET flash)
+  add_custom_target(
+    flash
+    DEPENDS nuttx_post_build
+    COMMAND
+      ${CMAKE_COMMAND} -E env sh ${AMEBA_TOOLS_DIR}/ameba_flash.sh ${AMEBA_SDK}
+      ${AMEBA_FLASH_PROFILE} ${AMEBA_AUTOCONF} ${AMEBA_PREBUILT}
+      ${CMAKE_BINARY_DIR}/nuttx.bin
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+    USES_TERMINAL VERBATIM
+    COMMENT "Flashing Ameba ${AMEBA_PY_SOC} over ${AMEBA_PORT} (AMEBA_PORT 
env)"
+  )
+endif()
diff --git a/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake 
b/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake
new file mode 100644
index 00000000000..b2121ccfc74
--- /dev/null
+++ b/arch/arm/src/common/ameba/cmake/ameba_sdk.cmake
@@ -0,0 +1,64 @@
+# 
##############################################################################
+# arch/arm/src/common/ameba/cmake/ameba_sdk.cmake
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# 
##############################################################################
+
+# Resolve the ameba-rtos SDK checkout + asdk toolchain dir for the CMake build,
+# and sanity-check the compiler.  The SDK + asdk toolchain are provisioned by 
`.
+# tools/ameba/env.sh` before cmake, which puts the compiler on PATH for the
+# standard probe -- this is why no per-chip hook is needed in the shared arch
+# Toolchain.cmake.  Included by the arch chip CMakeLists BEFORE it builds the
+# SDK-relative source/include lists, so AMEBA_SDK is available to them.
+
+include_guard(GLOBAL)
+
+set(_ameba_common_dir ${CMAKE_CURRENT_LIST_DIR}/..)
+
+# AMEBA_SDK: prefer the environment (set by env.sh / an external checkout), 
fall
+# back to the shared in-tree checkout.
+if(DEFINED ENV{AMEBA_SDK} AND EXISTS "$ENV{AMEBA_SDK}/component/soc")
+  set(AMEBA_SDK $ENV{AMEBA_SDK})
+elseif(EXISTS "${_ameba_common_dir}/ameba-rtos/component/soc")
+  set(AMEBA_SDK ${_ameba_common_dir}/ameba-rtos)
+else()
+  message(
+    FATAL_ERROR
+      "ameba-rtos SDK not found.  Source the build environment first:\n"
+      "  . tools/ameba/env.sh\n" "then re-run cmake.")
+endif()
+get_filename_component(AMEBA_SDK ${AMEBA_SDK} ABSOLUTE)
+
+# asdk install root (only needed by the packaging step); matches env.sh.
+if(DEFINED ENV{AMEBA_TOOLCHAIN_DIR} AND NOT "$ENV{AMEBA_TOOLCHAIN_DIR}"
+                                        STREQUAL "")
+  set(AMEBA_TOOLCHAIN_DIR $ENV{AMEBA_TOOLCHAIN_DIR})
+else()
+  set(AMEBA_TOOLCHAIN_DIR $ENV{HOME}/rtk-toolchain)
+endif()
+
+# The compiler must be the SDK-pinned asdk toolchain (put on PATH by env.sh); a
+# stray arm-none-eabi-gcc would not match the SDK's prebuilt archives.
+if(NOT "${CMAKE_C_COMPILER}" MATCHES "${AMEBA_TOOLCHAIN_DIR}")
+  message(
+    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")
+endif()
diff --git a/arch/arm/src/common/ameba/tools/ameba_fetch_sdk.sh 
b/arch/arm/src/common/ameba/tools/ameba_fetch_sdk.sh
index 7eba7602ec1..be87b4e67b1 100755
--- a/arch/arm/src/common/ameba/tools/ameba_fetch_sdk.sh
+++ b/arch/arm/src/common/ameba/tools/ameba_fetch_sdk.sh
@@ -49,7 +49,10 @@ if [ ! -d "$DEST/component/soc" ]; then
   # init + fetch <sha> is used to land an arbitrary pinned commit.)
   git init --quiet "$DEST"
   git -C "$DEST" remote add origin "$URL"
-  git -C "$DEST" fetch --quiet --depth 1 origin "$VERSION"
+  # --progress (not --quiet): the shallow fetch still pulls hundreds of MB, so
+  # show git's "Receiving objects" bar -- otherwise it looks hung.  --progress
+  # forces the bar even when stderr is not a TTY (e.g. CI logs).
+  git -C "$DEST" fetch --progress --depth 1 origin "$VERSION"
   git -C "$DEST" checkout --quiet FETCH_HEAD
 
   # Apply the NuttX build patches on top of the pinned commit.  Done only on a
diff --git a/arch/arm/src/common/ameba/tools/ameba_flash.sh 
b/arch/arm/src/common/ameba/tools/ameba_flash.sh
new file mode 100755
index 00000000000..ab9d4bb6915
--- /dev/null
+++ b/arch/arm/src/common/ameba/tools/ameba_flash.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+############################################################################
+# arch/arm/src/common/ameba/tools/ameba_flash.sh
+#
+# Download the built Ameba images to the chip over serial, via the SDK's
+# AmebaFlash.py.  This is the single implementation shared by the make `flash`
+# target (tools/ameba/Config.mk) and the cmake `flash` target
+# (common/ameba/cmake/ameba_board.cmake), so both flash identically.
+#
+# Two images are written, each at its own flash offset:
+#   boot.bin  (SDK bootloader, prebuilt) @ CONFIG_FLASH_BOOT_OFFSET
+#   nuttx.bin (AP+NP application image)   @ CONFIG_FLASH_(APP_)OTA1_OFFSET
+#
+# The offsets are NOT hardcoded: they are read from the config-derived
+# platform_autoconf.h, so a flash-layout change is tracked automatically.  The
+# app-slot macro is CONFIG_FLASH_APP_OTA1_OFFSET on some ICs (RTL8720F) and
+# CONFIG_FLASH_OTA1_OFFSET on others (RTL8721Dx); match either.
+#
+# Usage: ameba_flash.sh <sdk> <profile> <autoconf> <prebuilt_dir> <nuttx_bin>
+#   Serial port + baud come from the environment (so a cmake custom target can
+#   forward them without a reconfigure):
+#     AMEBA_PORT   serial port (required, e.g. /dev/ttyUSB0)
+#     AMEBA_BAUD   baud rate   (default 1500000)
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+set -e
+
+SDK="$1"
+PROFILE_NAME="$2"
+AUTOCONF="$3"
+PREBUILT="$4"
+NUTTX_BIN="$5"
+
+AMEBA_BAUD="${AMEBA_BAUD:-1500000}"
+
+if [ -z "$AMEBA_PORT" ]; then
+  echo "FLASH error: Missing serial port device." >&2
+  echo "USAGE: AMEBA_PORT=/dev/ttyUSB0 [AMEBA_BAUD=$AMEBA_BAUD] <flash cmd>" 
>&2
+  exit 1
+fi
+
+BOOT_OFFSET=$(awk '$2=="CONFIG_FLASH_BOOT_OFFSET"{print $3}' "$AUTOCONF" 
2>/dev/null)
+APP_OFFSET=$(awk '$2 ~ /^CONFIG_FLASH_(APP_)?OTA1_OFFSET$/{print $3}' \
+             "$AUTOCONF" 2>/dev/null)
+if [ -z "$BOOT_OFFSET" ] || [ -z "$APP_OFFSET" ]; then
+  echo "FLASH error: could not read flash offsets from $AUTOCONF" >&2
+  echo "  Build first so platform_autoconf.h is generated." >&2
+  exit 1
+fi
+
+AMEBAPY="$(cat "$SDK/.amebapy/bindir" 2>/dev/null)/python"
+[ -x "$AMEBAPY" ] || AMEBAPY="python3"
+
+SCRIPT="$SDK/tools/ameba/Flash/AmebaFlash.py"
+[ -f "$SCRIPT" ] || { echo "FLASH error: AmebaFlash.py not found at $SCRIPT" 
>&2; exit 1; }
+
+PROFILE="$SDK/tools/ameba/Flash/Devices/Profiles/$PROFILE_NAME.rdev"
+[ -f "$PROFILE" ] || { echo "FLASH error: profile not found: $PROFILE" >&2; 
exit 1; }
+
+for spec in "$PREBUILT/boot.bin:$BOOT_OFFSET" "$NUTTX_BIN:$APP_OFFSET"; do
+  IMG="${spec%:*}"
+  ADDR="${spec##*:}"
+  if [ ! -f "$IMG" ]; then
+    echo "FLASH error: image not found: $IMG (build first)" >&2
+    exit 1
+  fi
+  echo "FLASH: $IMG @ $ADDR"
+  "$AMEBAPY" "$SCRIPT" \
+    --download \
+    --profile "$PROFILE" \
+    --memory-type nor \
+    --image "$IMG" \
+    --start-address "$ADDR" \
+    --port "$AMEBA_PORT" \
+    --baudrate "$AMEBA_BAUD" \
+    --log-level info
+done
diff --git a/arch/arm/src/common/ameba/tools/ameba_gen_ldscript.sh 
b/arch/arm/src/common/ameba/tools/ameba_gen_ldscript.sh
new file mode 100755
index 00000000000..d65d571aa6f
--- /dev/null
+++ b/arch/arm/src/common/ameba/tools/ameba_gen_ldscript.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+############################################################################
+# arch/arm/src/common/ameba/tools/ameba_gen_ldscript.sh
+#
+# Generate the combined Ameba AP image2 linker script (ld.script.gen) the
+# `nuttx` ELF is linked with, WITHOUT editing any SDK source file.  This is the
+# single implementation of the three-step recipe the make PREBUILD used inline,
+# so the make and cmake builds produce a byte-identical script:
+#
+#   1. C-preprocess ameba_img2_all.ld (it #includes ameba_layout.ld and the
+#      config-derived platform_autoconf.h, staged as
+#      project_<proj>/platform_autoconf.h on the include path).
+#   2. Append ameba_rom_symbol_acut_s.ld (ROM symbol addresses).
+#   3. Fold NuttX's .vectors orphan section into the loadable SRAM data region
+#      so the large power-of-two aligned vector table does not land in and
+#      overflow the tiny fixed KM4_IMG2_ENTRY region.
+#
+# This reproduces the SDK-generated rlx8721d.ld; the SDK tree stays read-only.
+#
+# Usage: ameba_gen_ldscript.sh <cc> <img2_ld> <rom_ld> <autoconf> \
+#                              <prebuilt_dir> <ap_project> <out>
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+set -e
+
+CC="$1"
+IMG2_LD="$2"
+ROM_LD="$3"
+AUTOCONF="$4"
+PREBUILT="$5"
+AP_PROJECT="$6"
+OUT="$7"
+
+if [ -z "$CC" ] || [ -z "$IMG2_LD" ] || [ -z "$ROM_LD" ] || [ -z "$AUTOCONF" ] 
\
+   || [ -z "$PREBUILT" ] || [ -z "$AP_PROJECT" ] || [ -z "$OUT" ]; then
+  echo "usage: ameba_gen_ldscript.sh <cc> <img2_ld> <rom_ld> <autoconf>" \
+       "<prebuilt_dir> <ap_project> <out>" >&2
+  exit 1
+fi
+
+# Stage the autoconf where ameba_img2_all.ld's #include resolves it (-I 
prebuilt
+# then #include "project_<proj>/platform_autoconf.h").
+mkdir -p "$PREBUILT/project_$AP_PROJECT"
+cp "$AUTOCONF" "$PREBUILT/project_$AP_PROJECT/platform_autoconf.h"
+
+# 1) preprocess, 2) append ROM symbols
+"$CC" -E -P -xc -c "$IMG2_LD" -o "$OUT" -I "$PREBUILT"
+cat "$ROM_LD" >> "$OUT"
+
+# 3) fold NuttX .vectors into the loadable SRAM data region
+sed -i 's|^\([[:space:]]*\)\*(\.data\*)|\1*(.vectors*)\n\1*(.data*)|' "$OUT"
diff --git a/arch/arm/src/common/ameba/tools/ameba_package.sh 
b/arch/arm/src/common/ameba/tools/ameba_package.sh
new file mode 100755
index 00000000000..3c8d40e7035
--- /dev/null
+++ b/arch/arm/src/common/ameba/tools/ameba_package.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+############################################################################
+# arch/arm/src/common/ameba/tools/ameba_package.sh
+#
+# Package the linked Ameba AP image2 ELF (`nuttx`) into a flashable nuttx.bin,
+# folding the prototype package_app.sh into the NuttX build.  This is the 
single
+# implementation of the make-side ameba_board.mk POSTBUILD, invoked from both
+# the make POSTBUILD and the cmake nuttx_post_build target so the two build
+# systems produce an identical image.  Steps:
+#
+#   1. Replicate the SDK image2 postbuild prologue (copy map/axf, nm/objdump).
+#   2. (Re)build the NP (km0) image2 + boot from the pinned SDK source, fed the
+#      AP disassembly so the WiFi "noused" generator keeps only referenced APIs
+#      (must run AFTER the AP link -- see ameba_build_np.sh).
+#   3. Run the SDK AP (km4) image2 postbuild.cmake (axf2bin) -> 
km4_image2_all.bin.
+#   4. Run the SDK firmware_package postbuild.cmake combining the AP + NP 
image2
+#      into the packed app image, copied out as nuttx.bin.
+#
+# Unlike the make build (whose parse-time toolchain.mk puts asdk on PATH), this
+# script runs in the build tool's environment, so it resolves the SDK-pinned
+# asdk toolchain + prebuilts + python venv itself and prepends them to PATH.
+#
+# Usage: ameba_package.sh <sdk> <py_soc> <soc_name> <prebuilt> <ap_project> \
+#                         <km_proj> <np_target> <toolchain_dir> <nuttx_elf> \
+#                         <out_bin>
+#
+#   <np_target>  NP-core image name (km0 on RTL8721Dx, km4ns on RTL8720F)
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+set -e
+
+SDK="$1"
+PY_SOC="$2"
+SOC_NAME="$3"
+PREBUILT="$4"
+AP_PROJECT="$5"
+KM_PROJ="$6"
+NP_TARGET="$7"
+TCDIR="${8:-$HOME/rtk-toolchain}"
+NUTTX_ELF="$9"
+OUT_BIN="${10}"
+
+TOOLS_DIR=$(CDPATH= cd "$(dirname "$0")" && pwd)
+
+if [ -z "$SDK" ] || [ -z "$OUT_BIN" ]; then
+  echo "usage: ameba_package.sh <sdk> <py_soc> <soc_name> <prebuilt>" \
+       "<ap_project> <km_proj> <np_target> <toolchain_dir> <nuttx_elf>" \
+       "<out_bin>" >&2
+  exit 1
+fi
+
+echo "PACK: nuttx.bin (Ameba AP $AP_PROJECT image2 + NP $NP_TARGET image2)"
+
+# --- Resolve the SDK-pinned asdk toolchain + prebuilts + venv onto PATH ------
+
+VER=$(sed -n 's/.*v_ASDK_VER[ \t][ \t]*\([0-9.][0-9.]*\).*/\1/p' \
+      "$SDK/cmake/global_define.cmake")
+TC_CMAKE="$SDK/cmake/toolchain/ameba-toolchain-asdk-$VER.cmake"
+BUILD=$(sed -n 's/.*ToolChainVerMinor[ \t][ \t]*\([0-9][0-9]*\).*/\1/p' 
"$TC_CMAKE")
+ASDK_BIN="$TCDIR/asdk-$VER-$BUILD/linux/newlib/bin"
+[ -d "$ASDK_BIN" ] && PATH="$ASDK_BIN:$PATH"
+
+PBV=$(sed -n 's/^PREBUILTS_VERSION=//p' "$SDK/env.sh" | head -1)
+[ -n "$PBV" ] && PATH="$TCDIR/prebuilts-linux-$PBV/bin:$PATH"
+
+# Provision + resolve the python interpreter the SDK cmake steps need.
+sh "$TOOLS_DIR/ameba_setup_env.sh" "$SDK" "$TCDIR"
+VENV_BIN=$(cat "$SDK/.amebapy/bindir" 2>/dev/null || true)
+[ -n "$VENV_BIN" ] && PATH="$VENV_BIN:$PATH"
+export PATH
+
+CROSSDEV=arm-none-eabi-
+NM="${CROSSDEV}nm"
+OBJDUMP="${CROSSDEV}objdump"
+STRIP="${CROSSDEV}strip"
+OBJCOPY="${CROSSDEV}objcopy"
+SIZE="${CROSSDEV}size"
+CMAKE="${CMAKE:-cmake}"
+
+SOC_PROJ="$SDK/component/soc/$SOC_NAME/project"
+KM4_PROJ="$SOC_PROJ/$KM_PROJ"
+PKGDIR="$PREBUILT/pkg"
+
+# --- 1. image2 postbuild prologue -------------------------------------------
+
+rm -rf "$PKGDIR"
+mkdir -p "$PKGDIR"
+cp "$NUTTX_ELF" "$PKGDIR/target_img2.axf"
+"$NM" "$PKGDIR/target_img2.axf" | sort > "$PKGDIR/target_img2.map"
+"$OBJDUMP" -d "$PKGDIR/target_img2.axf" > "$PKGDIR/target_img2.asm"
+
+# --- 2. (re)build NP (km0) image2 from SDK source, fed the AP disassembly ----
+
+sh "$TOOLS_DIR/ameba_build_np.sh" "$SDK" "$PY_SOC" "$PREBUILT" \
+   "$PKGDIR/target_img2.asm" "$NP_TARGET" "$AP_PROJECT"
+
+cp "$PKGDIR/target_img2.axf" "$PKGDIR/target_pure_img2.axf"
+"$STRIP" "$PKGDIR/target_pure_img2.axf"
+cp "$PREBUILT/config_km4" "$PKGDIR/.config_km4"
+cp "$PREBUILT/config_fw" "$PKGDIR/.config"
+cp "$PREBUILT/${NP_TARGET}_image2_all.bin" 
"$PKGDIR/${NP_TARGET}_image2_all.bin"
+printf '{\n    "soc": {\n        "name": "%s"\n    }\n}\n' "$PY_SOC" \
+  > "$PKGDIR/soc_info.json"
+
+# --- 3. AP (km4) image2 axf2bin -> km4_image2_all.bin -----------------------
+
+TARGET_SOC="$PY_SOC" "$CMAKE" \
+  -Dc_BASEDIR="$SDK" \
+  -Dc_CMAKE_FILES_DIR="$SDK/cmake" \
+  -Dc_SOC_PROJECT_DIR="$SOC_PROJ" \
+  -Dc_MCU_PROJECT_DIR="$KM4_PROJ" \
+  -Dc_MCU_PROJECT_NAME="$AP_PROJECT" \
+  -Dc_MCU_KCONFIG_FILE="$PKGDIR/.config_km4" \
+  -Dc_SDK_IMAGE_TARGET_DIR="$PKGDIR" \
+  -DKM4_BUILDDIR= \
+  -DFINAL_IMAGE_DIR="$PKGDIR" \
+  -DBUILD_TYPE=NONE -DANALYZE_MP_IMG=0 -DDAILY_BUILD=0 \
+  -DEXTERN_DIR="$PKGDIR" -DCODE_ANALYZE_RETRY= \
+  -DIMAGESCRIPTDIR="$SDK/tools/image_scripts" \
+  -DCMAKE_SIZE="$SIZE" -DCMAKE_OBJCOPY="$OBJCOPY" \
+  -P "$KM4_PROJ/make/image2/postbuild.cmake"
+
+# --- 4. firmware_package: combine AP + NP image2 -> app.bin -> nuttx.bin -----
+
+TARGET_SOC="$PY_SOC" "$CMAKE" \
+  -Dc_BASEDIR="$SDK" \
+  -Dc_CMAKE_FILES_DIR="$SDK/cmake" \
+  -Dc_MCU_KCONFIG_FILE="$PKGDIR/.config" \
+  -Dc_SOC_PROJECT_DIR="$SOC_PROJ" \
+  -Dc_SDK_IMAGE_TARGET_DIR= \
+  -Dc_IMAGE_OUTPUT_DIR="$PKGDIR" \
+  -Dc_APP_BINARY_NAME=app.bin \
+  -Dc_IMAGE1_ALL_FILES= \
+  
-Dc_IMAGE2_ALL_FILES="$PKGDIR/${NP_TARGET}_image2_all.bin;$PKGDIR/${AP_PROJECT}_image2_all.bin"
 \
+  -Dc_IMAGE3_ALL_FILES= \
+  -DFINAL_IMAGE_DIR="$PKGDIR" \
+  -DANALYZE_MP_IMG=0 -DEXTERN_DIR="$PKGDIR" \
+  -P "$SOC_PROJ/postbuild.cmake"
+
+cp "$PKGDIR/app.bin" "$OUT_BIN"
+echo "PACK: wrote $OUT_BIN"
+# Flash hint is caller-supplied (AMEBA_FLASH_HINT) so the make and cmake build
+# paths each print their own flash command; printed only when provided.
+if [ -n "$AMEBA_FLASH_HINT" ]; then
+  echo "      Flash with: $AMEBA_FLASH_HINT"
+fi
diff --git a/arch/arm/src/rtl8720f/CMakeLists.txt 
b/arch/arm/src/rtl8720f/CMakeLists.txt
index f80b1a8f18f..37bcfb83d0b 100644
--- a/arch/arm/src/rtl8720f/CMakeLists.txt
+++ b/arch/arm/src/rtl8720f/CMakeLists.txt
@@ -29,6 +29,12 @@ set(AMEBA_COMMON ${CMAKE_CURRENT_LIST_DIR}/../common/ameba)
 
 list(APPEND SRCS ${AMEBA_COMMON}/ameba_os_wrap.c)
 
+# km4tz<->km4ns IPC bring-up: needed by the SDK flash erase/program path
+# (inter-core XIP pause) AND by WiFi, so compile it whenever either is enabled.
+if(CONFIG_RTL8720F_WIFI OR CONFIG_RTL8720F_FLASH_FS)
+  list(APPEND SRCS ameba_ipc.c)
+endif()
+
 if(CONFIG_RTL8720F_WIFI)
   list(APPEND SRCS ameba_wifi_init.c ${AMEBA_COMMON}/ameba_kv.c)
   if(CONFIG_NET)
@@ -42,3 +48,136 @@ endif()
 
 target_include_directories(arch PRIVATE ${AMEBA_COMMON})
 target_sources(arch PRIVATE ${SRCS})
+
+# 
##############################################################################
+# Vendor-SDK build machinery (shared mechanism in common/ameba/cmake).  This
+# IC's differing inputs are set here (RTL8720F: km4tz AP core, km4ns NP core).
+# 
##############################################################################
+
+set(AMEBA_SOC_NAME RTL8720F)
+set(AMEBA_PY_SOC RTL8720F)
+set(AMEBA_AP_PROJECT km4tz)
+set(AMEBA_KM_PROJ project_km4tz)
+set(AMEBA_NP_TARGET km4ns)
+set(AMEBA_CFG_WIFI ${CONFIG_RTL8720F_WIFI})
+set(AMEBA_CFG_FLASHFS ${CONFIG_RTL8720F_FLASH_FS})
+
+# Resolve AMEBA_SDK / asdk toolchain (provisioned by `. tools/ameba/env.sh`)
+# before the SDK-relative source lists below reference it.
+include(${AMEBA_COMMON}/cmake/ameba_sdk.cmake)
+
+set(AMEBA_SOC ${AMEBA_SDK}/component/soc/${AMEBA_SOC_NAME})
+set(AMEBA_PREBUILT ${NUTTX_BOARD_DIR}/prebuilt)
+set(AMEBA_WIFI_DIR ${AMEBA_COMMON}/wifi)
+
+# fwlib register-layer sources compiled into libameba_fwlib.a, plus the
+# NuttX-owned image2 entry (ameba_app_start.c, IC-specific).
+set(AMEBA_FWLIB_SRCS
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_arch.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_loguart.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_api.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_ram.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_clk.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_pmctimer.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_pmu.c
+    ${CMAKE_CURRENT_LIST_DIR}/ameba_app_start.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_mpu_ram.c
+    ${AMEBA_SOC}/fwlib/ram_km4tz/ameba_data_flashclk.c
+    ${AMEBA_SOC}/fwlib/ram_km4tz/ameba_flashclk.c
+    ${AMEBA_SOC}/fwlib/ram_km4tz/ameba_pinmap.c
+    ${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/ameba_flashcfg.c
+    ${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/ameba_pinmapcfg.c)
+
+if(CONFIG_RTL8720F_FLASH_FS)
+  list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_flash_ram.c)
+endif()
+
+# Silence a couple of warnings the vendored SDK sources trip under NuttX's
+# warning set, scoped to this fwlib compile only (never relaxing NuttX's own):
+# -Wno-int-conversion: the SDK passes NULL to irq_register()'s u32 "Data"
+# (interrupt context) argument in many places -- an intentional idiom.
+# -Wno-shadow: SDK swlib/log.c shadows a file-scope global with a parameter.
+set(AMEBA_FWLIB_INC
+    -Wno-int-conversion
+    -Wno-shadow
+    -I${AMEBA_COMMON}/sdk_shim
+    -I${AMEBA_SOC}/fwlib/include
+    -I${AMEBA_SOC}/fwlib/include/rom
+    -I${AMEBA_SOC}/swlib
+    -I${AMEBA_SOC}/hal/include
+    -I${AMEBA_SOC}/hal/src
+    -I${AMEBA_SDK}/component/soc/common/include
+    -I${AMEBA_SDK}/component/soc/common/include/cmsis
+    -I${AMEBA_SOC}/app/monitor/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/common
+    -I${AMEBA_SOC}/misc
+    -I${AMEBA_SDK}/component/os/os_wrapper/include
+    -I${AMEBA_SDK}/component/ssl/mbedtls-3.6.5/include
+    -I${AMEBA_SDK}/component/soc/common/crashdump/include
+    -I${AMEBA_PREBUILT})
+
+# Host WiFi glue -> libameba_wifi.a (identical source/include set to the other
+# Ameba ICs; shim include first, SDK autoconf force-included).
+set(AMEBA_WIFI_SRCS
+    ${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/ameba_wificfg.c
+    ${AMEBA_SDK}/component/wifi/common/rtw_task_size.c
+    ${AMEBA_SDK}/component/wifi/common/rtw_event.c
+    ${AMEBA_SDK}/component/soc/common/diagnose/ameba_diagnose_none.c
+    
${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_supplicant/wifi_p2p_disable.c
+    ${AMEBA_WIFI_DIR}/ameba_wifi_depend.c
+    ${AMEBA_WIFI_DIR}/ameba_wifi.c)
+
+set(AMEBA_WIFI_INC
+    -include
+    ${AMEBA_PREBUILT}/platform_autoconf.h
+    -include
+    ${AMEBA_WIFI_DIR}/include/ameba_lwip_off.h
+    -I${AMEBA_WIFI_DIR}/include
+    -I${AMEBA_WIFI_DIR}/..
+    -I${AMEBA_SDK}/component/wifi/api
+    -I${AMEBA_SDK}/component/wifi/common
+    -I${AMEBA_SDK}/component/wifi/driver/include
+    -I${AMEBA_SDK}/component/wifi/driver/intf
+    -I${AMEBA_SDK}/component/wifi/whc
+    -I${AMEBA_SDK}/component/wifi/whc/whc_host_rtos
+    -I${AMEBA_SDK}/component/wifi/whc/whc_host_rtos/ipc
+    -I${AMEBA_SDK}/component/at_cmd
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_supplicant
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_lite
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_lite/rom
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/src
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/src/utils
+    -I${AMEBA_SDK}/component/wifi/rtk_app/wifi_auto_reconnect
+    -I${AMEBA_SDK}/component/network
+    -I${AMEBA_SDK}/component/soc/common/diagnose
+    -I${AMEBA_SOC}/app/monitor/include
+    -I${AMEBA_SOC}/fwlib/include
+    -I${AMEBA_SOC}/fwlib/include/rom
+    -I${AMEBA_SOC}/swlib
+    -I${AMEBA_SOC}/hal/include
+    -I${AMEBA_SOC}/misc
+    -I${AMEBA_SDK}/component/soc/common/include
+    -I${AMEBA_SDK}/component/soc/common/include/cmsis
+    -I${AMEBA_SDK}/component/os/os_wrapper/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/common
+    -I${AMEBA_SDK}/component/ssl/mbedtls-3.6.5/include
+    -I${AMEBA_PREBUILT})
+
+# KM4TZ-side host WiFi control libs.  Unlike RTL8721Dx, lib_coex.a is NP-side
+# (km4ns) on RTL8720F and is NOT linked into the AP image.
+set(_ameba_app_lib ${AMEBA_SOC}/project/${AMEBA_KM_PROJ}/lib/application)
+set(AMEBA_WIFI_APP_LIBS
+    ${_ameba_app_lib}/lib_wifi_whc_ap.a ${_ameba_app_lib}/lib_wifi_rtk_app.a
+    ${_ameba_app_lib}/lib_wifi_com_sec.a ${_ameba_app_lib}/lib_wpa_lite.a)
+
+# RTL8720F pulls the ROM symbol implementations from lib_rom.a via a
+# whole-archive link (TrustZone off in this config -> lib_rom.a, not
+# lib_rom_tz.a), in addition to the ROM symbol addresses appended to the
+# generated ld script.
+set(_ameba_soc_lib ${AMEBA_SOC}/project/${AMEBA_KM_PROJ}/lib/soc)
+set(AMEBA_EXTRA_LINK_OPTIONS -Wl,--whole-archive ${_ameba_soc_lib}/lib_rom.a
+                             -Wl,--no-whole-archive)
+
+include(${AMEBA_COMMON}/cmake/ameba_board.cmake)
diff --git a/arch/arm/src/rtl8721dx/CMakeLists.txt 
b/arch/arm/src/rtl8721dx/CMakeLists.txt
index 3b47d76726b..423a80470fe 100644
--- a/arch/arm/src/rtl8721dx/CMakeLists.txt
+++ b/arch/arm/src/rtl8721dx/CMakeLists.txt
@@ -42,3 +42,136 @@ endif()
 
 target_include_directories(arch PRIVATE ${AMEBA_COMMON})
 target_sources(arch PRIVATE ${SRCS})
+
+# 
##############################################################################
+# Vendor-SDK build machinery (SDK libs, image2 ld script, link flags, nuttx.bin
+# packaging).  This IC's differing inputs are set here; the shared mechanism
+# lives in common/ameba/cmake/ameba_board.cmake (mirrors the make-side split
+# between arch/.../rtl8721dx/Make.defs + ameba_board.mk and its board wrapper).
+# 
##############################################################################
+
+# Per-IC identifiers (see the make ameba_board.mk of the same names).
+set(AMEBA_SOC_NAME amebadplus)
+set(AMEBA_PY_SOC RTL8721Dx)
+set(AMEBA_AP_PROJECT km4)
+set(AMEBA_KM_PROJ project_km4)
+set(AMEBA_NP_TARGET km0)
+set(AMEBA_CFG_WIFI ${CONFIG_RTL8721DX_WIFI})
+set(AMEBA_CFG_FLASHFS ${CONFIG_RTL8721DX_FLASH_FS})
+
+# Resolve AMEBA_SDK / asdk toolchain (provisioned by `. tools/ameba/env.sh`)
+# before the SDK-relative source lists below reference it.
+include(${AMEBA_COMMON}/cmake/ameba_sdk.cmake)
+
+set(AMEBA_SOC ${AMEBA_SDK}/component/soc/${AMEBA_SOC_NAME})
+set(AMEBA_PREBUILT ${NUTTX_BOARD_DIR}/prebuilt)
+set(AMEBA_WIFI_DIR ${AMEBA_COMMON}/wifi)
+
+# fwlib register-layer sources compiled from SDK source into libameba_fwlib.a,
+# plus the NuttX-owned image2 entry (ameba_app_start.c, IC-specific).
+set(AMEBA_FWLIB_SRCS
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_arch.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_loguart.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_api.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_ram.c
+    ${AMEBA_SOC}/misc/ameba_pmu.c
+    ${AMEBA_SOC}/swlib/log.c
+    ${AMEBA_SOC}/swlib/sscanf_minimal.c
+    ${CMAKE_CURRENT_LIST_DIR}/ameba_app_start.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_mpu_ram.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_bor.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_reset.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_clk.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_rtc_io.c
+    ${AMEBA_SOC}/fwlib/ram_common/ameba_adc.c
+    ${AMEBA_SOC}/fwlib/ram_km4/ameba_data_flashclk.c)
+
+if(CONFIG_RTL8721DX_FLASH_FS)
+  list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_flash_ram.c)
+endif()
+
+# Silence a couple of warnings the vendored SDK sources trip under NuttX's
+# warning set, scoped to this fwlib compile only (never relaxing NuttX's own):
+# -Wno-int-conversion: the SDK passes NULL to irq_register()'s u32 "Data"
+# (interrupt context) argument in many places -- an intentional idiom.
+# -Wno-shadow: SDK swlib/log.c shadows a file-scope global with a parameter.
+set(AMEBA_FWLIB_INC
+    -Wno-int-conversion
+    -Wno-shadow
+    -mcmse
+    -I${AMEBA_COMMON}/sdk_shim
+    -I${AMEBA_SOC}/fwlib/include
+    -I${AMEBA_SOC}/fwlib/include/rom
+    -I${AMEBA_SOC}/swlib
+    -I${AMEBA_SOC}/hal/include
+    -I${AMEBA_SOC}/hal/src
+    -I${AMEBA_SDK}/component/soc/common/include
+    -I${AMEBA_SDK}/component/soc/common/include/cmsis
+    -I${AMEBA_SOC}/app/monitor/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/common
+    -I${AMEBA_SOC}/misc
+    -I${AMEBA_SDK}/component/os/os_wrapper/include
+    -I${AMEBA_SDK}/component/soc/common/crashdump/include
+    -I${AMEBA_PREBUILT})
+
+# Host WiFi glue -> libameba_wifi.a (built with the vendor WiFi include set; 
the
+# shim include dir comes FIRST so its <lwip_netconf.h> shadows the SDK's, and
+# the SDK autoconf is force-included so every source sees the vendor WiFi 
config
+# macros).
+set(AMEBA_WIFI_SRCS
+    ${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/ameba_wificfg.c
+    ${AMEBA_SDK}/component/wifi/common/rtw_task_size.c
+    ${AMEBA_SDK}/component/wifi/common/rtw_event.c
+    ${AMEBA_SDK}/component/soc/common/diagnose/ameba_diagnose_none.c
+    
${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_supplicant/wifi_p2p_disable.c
+    ${AMEBA_WIFI_DIR}/ameba_wifi_depend.c
+    ${AMEBA_WIFI_DIR}/ameba_wifi.c)
+
+set(AMEBA_WIFI_INC
+    -include
+    ${AMEBA_PREBUILT}/platform_autoconf.h
+    -include
+    ${AMEBA_WIFI_DIR}/include/ameba_lwip_off.h
+    -I${AMEBA_WIFI_DIR}/include
+    -I${AMEBA_WIFI_DIR}/..
+    -I${AMEBA_SDK}/component/wifi/api
+    -I${AMEBA_SDK}/component/wifi/common
+    -I${AMEBA_SDK}/component/wifi/driver/include
+    -I${AMEBA_SDK}/component/wifi/driver/intf
+    -I${AMEBA_SDK}/component/wifi/whc
+    -I${AMEBA_SDK}/component/wifi/whc/whc_host_rtos
+    -I${AMEBA_SDK}/component/wifi/whc/whc_host_rtos/ipc
+    -I${AMEBA_SDK}/component/at_cmd
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_supplicant
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_lite
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/wpa_lite/rom
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/src
+    -I${AMEBA_SDK}/component/wifi/wpa_supplicant/src/utils
+    -I${AMEBA_SDK}/component/wifi/rtk_app/wifi_auto_reconnect
+    -I${AMEBA_SDK}/component/network
+    -I${AMEBA_SDK}/component/soc/common/diagnose
+    -I${AMEBA_SOC}/app/monitor/include
+    -I${AMEBA_SOC}/fwlib/include
+    -I${AMEBA_SOC}/fwlib/include/rom
+    -I${AMEBA_SOC}/swlib
+    -I${AMEBA_SOC}/hal/include
+    -I${AMEBA_SOC}/misc
+    -I${AMEBA_SDK}/component/soc/common/include
+    -I${AMEBA_SDK}/component/soc/common/include/cmsis
+    -I${AMEBA_SDK}/component/os/os_wrapper/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/${AMEBA_SOC_NAME}/include
+    -I${AMEBA_SDK}/component/soc/usrcfg/common
+    -I${AMEBA_SDK}/component/ssl/mbedtls-3.6.5/include
+    -I${AMEBA_PREBUILT})
+
+# KM4-side host WiFi control libs from the pinned SDK (STA-PSK reduced set).
+# lib_coex.a is an AP-side lib on RTL8721Dx (contrast RTL8720F, where it is
+# NP-side and not linked here).
+set(_ameba_app_lib ${AMEBA_SOC}/project/${AMEBA_KM_PROJ}/lib/application)
+set(AMEBA_WIFI_APP_LIBS
+    ${_ameba_app_lib}/lib_wifi_whc_ap.a ${_ameba_app_lib}/lib_wifi_rtk_app.a
+    ${_ameba_app_lib}/lib_wifi_com_sec.a ${_ameba_app_lib}/lib_wpa_lite.a
+    ${_ameba_app_lib}/lib_coex.a)
+
+include(${AMEBA_COMMON}/cmake/ameba_board.cmake)
diff --git a/boards/arm/rtl8720f/rtl8720f_evb/CMakeLists.txt 
b/boards/arm/rtl8720f/rtl8720f_evb/CMakeLists.txt
index ae06cd7d352..1ad0a64ce68 100644
--- a/boards/arm/rtl8720f/rtl8720f_evb/CMakeLists.txt
+++ b/boards/arm/rtl8720f/rtl8720f_evb/CMakeLists.txt
@@ -20,17 +20,9 @@
 #
 # 
##############################################################################
 
-# The RTL8720F (Ameba WHC) port currently builds via the make-based build only.
-# The CMake path does not yet wire up the vendor-SDK machinery (SDK fetch,
-# libameba_fwlib.a/libameba_wifi.a, the image2 entry ameba_app_start.c, the SDK
-# image2 linker-script generation, the NP-image build and the nuttx.bin
-# packaging) that boards/.../scripts/Make.defs -> arch/.../ameba_board.mk
-# provides, so a CMake configure would not produce a flashable image.  Fail 
fast
-# with a clear message instead of half-building.
-message(
-  FATAL_ERROR
-    "rtl8720f_evb (RTL8720F, Ameba WHC) currently supports the make build "
-    "only; CMake is not yet supported.  Build with:\n"
-    "  ./tools/configure.sh rtl8720f_evb:nsh && make")
+# The vendor-SDK build machinery (SDK libs, image2 ld script, link flags and 
the
+# nuttx.bin packaging POSTBUILD / nuttx_post_build target) is wired up from the
+# shared arch/arm/src/common/ameba/cmake/ameba_board.cmake, included by this
+# IC's arch CMakeLists.  Nothing IC- or board-specific is needed here.
 
 add_subdirectory(src)
diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt 
b/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt
index 97130bd6be5..92afbd68e9b 100644
--- a/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt
+++ b/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt
@@ -24,4 +24,5 @@ set(SRCS rtl8720f_boot.c rtl8720f_bringup.c)
 
 target_sources(board PRIVATE ${SRCS})
 
-set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/ld.script")
+# LD_SCRIPT is not set here: the Ameba image2 linker script is generated
+# (prebuilt/ld.script.gen) and published by the shared ameba_board.cmake.
diff --git a/boards/arm/rtl8721dx/pke8721daf/CMakeLists.txt 
b/boards/arm/rtl8721dx/pke8721daf/CMakeLists.txt
index 4b36c87d0f9..b42d9f7a782 100644
--- a/boards/arm/rtl8721dx/pke8721daf/CMakeLists.txt
+++ b/boards/arm/rtl8721dx/pke8721daf/CMakeLists.txt
@@ -20,17 +20,9 @@
 #
 # 
##############################################################################
 
-# The RTL8721Dx (Ameba WHC) port currently builds via the make-based build 
only.
-# The CMake path does not yet wire up the vendor-SDK machinery (SDK fetch,
-# libameba_fwlib.a/libameba_wifi.a, the image2 entry ameba_app_start.c, the SDK
-# image2 linker-script generation, the NP-image build and the nuttx.bin
-# packaging) that boards/.../scripts/Make.defs -> arch/.../ameba_board.mk
-# provides, so a CMake configure would not produce a flashable image.  Fail 
fast
-# with a clear message instead of half-building.
-message(
-  FATAL_ERROR
-    "pke8721daf (RTL8721Dx, Ameba WHC) currently supports the make build "
-    "only; CMake is not yet supported.  Build with:\n"
-    "  ./tools/configure.sh pke8721daf:nsh && make")
+# The vendor-SDK build machinery (SDK libs, image2 ld script, link flags and 
the
+# nuttx.bin packaging POSTBUILD / nuttx_post_build target) is wired up from the
+# shared arch/arm/src/common/ameba/cmake/ameba_board.cmake, included by this
+# IC's arch CMakeLists.  Nothing IC- or board-specific is needed here.
 
 add_subdirectory(src)
diff --git a/boards/arm/rtl8721dx/pke8721daf/src/CMakeLists.txt 
b/boards/arm/rtl8721dx/pke8721daf/src/CMakeLists.txt
index dc5d6650e71..170196b66b9 100644
--- a/boards/arm/rtl8721dx/pke8721daf/src/CMakeLists.txt
+++ b/boards/arm/rtl8721dx/pke8721daf/src/CMakeLists.txt
@@ -24,4 +24,5 @@ set(SRCS rtl8721dx_boot.c rtl8721dx_bringup.c)
 
 target_sources(board PRIVATE ${SRCS})
 
-set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/ld.script")
+# LD_SCRIPT is not set here: the Ameba image2 linker script is generated
+# (prebuilt/ld.script.gen) and published by the shared ameba_board.cmake.
diff --git a/tools/ameba/Config.mk b/tools/ameba/Config.mk
index 38c953d0da3..577e063cb8a 100644
--- a/tools/ameba/Config.mk
+++ b/tools/ameba/Config.mk
@@ -40,72 +40,17 @@
 
 AMEBA_BAUD ?= 1500000
 
-# Flash offsets are NOT hardcoded here: they are read from the SDK flash
-# layout, surfaced in the regenerated platform_autoconf.h (AMEBA_AUTOCONF)
-# on every build.  This way a layout change (e.g. a bigger boot region that
-# pushes the app offset) is tracked automatically -- the .rdev profile only
-# supplies the on-chip flash-loader firmware, not the image placement.
-
-# The app-slot macro is spelled CONFIG_FLASH_APP_OTA1_OFFSET on some ICs
-# (e.g. RTL8720F) and CONFIG_FLASH_OTA1_OFFSET on others (e.g. RTL8721Dx);
-# match either.  boot is CONFIG_FLASH_BOOT_OFFSET on all.
-
-AMEBA_BOOT_OFFSET = $(strip $(shell awk '$$2=="CONFIG_FLASH_BOOT_OFFSET"{print 
$$3}' $(AMEBA_AUTOCONF) 2>/dev/null))
-AMEBA_APP_OFFSET  = $(strip $(shell awk '$$2 ~ 
/^CONFIG_FLASH_(APP_)?OTA1_OFFSET$$/{print $$3}' $(AMEBA_AUTOCONF) 2>/dev/null))
-
-# FLASH -- Download the built images via the SDK's AmebaFlash.py
-#
-# Two images are written, each at its own offset:
-#   boot.bin  (SDK bootloader, prebuilt) @ CONFIG_FLASH_BOOT_OFFSET
-#   nuttx.bin (AP+NP application image)   @ CONFIG_FLASH_APP_OTA1_OFFSET
-# boot.bin stays in the board prebuilt/ dir; only nuttx.bin lives in $(TOPDIR).
+# FLASH -- Download boot.bin + nuttx.bin via the SDK's AmebaFlash.py.  The 
whole
+# recipe (flash-offset lookup from the regenerated platform_autoconf.h, python 
/
+# .rdev-profile resolution, the two AmebaFlash.py downloads) lives in the 
shared
+# ameba_flash.sh, used by BOTH the make and cmake `flash` paths so they flash
+# identically.  Serial port + baud are passed to it through the environment.
 
 define FLASH
-       $(Q) if [ -z "$(AMEBA_PORT)" ]; then \
-               echo "FLASH error: Missing serial port device argument."; \
-               echo "USAGE: make flash AMEBA_PORT=/dev/ttyUSB0 [ 
AMEBA_BAUD=$(AMEBA_BAUD) ]"; \
-               exit 1; \
-       fi
-       $(Q) if [ -z "$(AMEBA_BOOT_OFFSET)" ] || [ -z "$(AMEBA_APP_OFFSET)" ]; 
then \
-               echo "FLASH error: could not read flash offsets from"; \
-               echo "  $(AMEBA_AUTOCONF)"; \
-               echo "  Run make first so platform_autoconf.h is generated."; \
-               exit 1; \
-       fi
-       $(Q) AMEBAPY="$$(cat $(AMEBA_SDK)/.amebapy/bindir 2>/dev/null)/python"; 
\
-               if [ ! -x "$$AMEBAPY" ]; then \
-                       AMEBAPY="python3"; \
-               fi; \
-               SCRIPT="$(AMEBA_SDK)/tools/ameba/Flash/AmebaFlash.py"; \
-               if [ ! -f "$$SCRIPT" ]; then \
-                       echo "FLASH error: AmebaFlash.py not found at 
$$SCRIPT"; \
-                       echo "  Has the ameba-rtos SDK been fetched?  Run make 
first."; \
-                       exit 1; \
-               fi; \
-               
PROFILE="$(AMEBA_SDK)/tools/ameba/Flash/Devices/Profiles/$(AMEBA_FLASH_PROFILE).rdev";
 \
-               if [ ! -f "$$PROFILE" ]; then \
-                       echo "FLASH error: profile not found: $$PROFILE"; \
-                       echo "  Set AMEBA_FLASH_PROFILE in the board's 
Make.defs."; \
-                       exit 1; \
-               fi; \
-               for spec in "$(AMEBA_PREBUILT)/boot.bin:$(AMEBA_BOOT_OFFSET)" \
-                           "$(TOPDIR)/nuttx.bin:$(AMEBA_APP_OFFSET)"; do \
-                       IMG="$${spec%:*}"; ADDR="$${spec##*:}"; \
-                       if [ ! -f "$$IMG" ]; then \
-                               echo "FLASH error: image not found: $$IMG (run 
make first)"; \
-                               exit 1; \
-                       fi; \
-                       echo "FLASH: $$IMG @ $$ADDR"; \
-                       $$AMEBAPY "$$SCRIPT" \
-                               --download \
-                               --profile "$$PROFILE" \
-                               --memory-type nor \
-                               --image "$$IMG" \
-                               --start-address "$$ADDR" \
-                               --port "$(AMEBA_PORT)" \
-                               --baudrate "$(or $(AMEBA_BAUD),1500000)" \
-                               --log-level info || exit 1; \
-               done
+       $(Q) AMEBA_PORT="$(AMEBA_PORT)" AMEBA_BAUD="$(AMEBA_BAUD)" \
+               $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_flash.sh \
+               $(AMEBA_SDK) $(AMEBA_FLASH_PROFILE) $(AMEBA_AUTOCONF) \
+               $(AMEBA_PREBUILT) $(TOPDIR)$(DELIM)nuttx.bin
 endef
 
 # ameba_menuconfig -- edit the vendor SDK menuconfig for this board using the
diff --git a/tools/ameba/env.sh b/tools/ameba/env.sh
new file mode 100755
index 00000000000..fbf03051ddd
--- /dev/null
+++ b/tools/ameba/env.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+############################################################################
+# tools/ameba/env.sh
+#
+# Source this before building the Realtek Ameba (RTL872x) boards:
+#
+#   . tools/ameba/env.sh
+#   cmake -B build -DBOARD_CONFIG=pke8721daf:nsh -GNinja && cmake --build build
+#     -- or --
+#   ./tools/configure.sh pke8721daf:nsh && make
+#
+# It resolves everything the build needs and exports it into the current shell,
+# reusing the same helper scripts the make build already uses (so make and 
cmake
+# share one setup path):
+#
+#   1. AMEBA_SDK   -- the ameba-rtos SDK checkout (external $AMEBA_SDK if 
valid,
+#                     else the shared in-tree one, fetched on demand).
+#   2. asdk toolchain -- the SDK-pinned arm-none-eabi (asdk) compiler, fetched 
if
+#                     absent and prepended to PATH.  This is why CMake works 
with
+#                     no per-chip toolchain hook: the compiler is simply on 
PATH
+#                     before `cmake` probes it, exactly like every other board.
+#   3. prebuilts + venv -- ninja/cmake bundle + the SDK python venv, prepended 
to
+#                     PATH for the image packaging steps.
+#
+# The make build does NOT require sourcing this (its Make.defs still 
auto-fetches
+# everything); it is optional there and REQUIRED for the CMake build.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# --- Must be sourced (it exports into the caller's shell) ------------------
+
+_ameba_self="${BASH_SOURCE:-${ZSH_VERSION:+${(%):-%x}}}"
+[ -n "$_ameba_self" ] || _ameba_self="$0"
+case "$0" in
+  *env.sh)
+    echo "ameba env.sh: source it, do not execute -- '. tools/ameba/env.sh'" 
>&2
+    exit 1 ;;
+esac
+
+_ameba_here="$(CDPATH= cd "$(dirname "$_ameba_self")" && pwd)"
+AMEBA_NUTTX="$(CDPATH= cd "$_ameba_here/../.." && pwd)"
+AMEBA_COMMON="$AMEBA_NUTTX/arch/arm/src/common/ameba"
+AMEBA_TOOLS="$AMEBA_COMMON/tools"
+AMEBA_TOOLCHAIN_DIR="${AMEBA_TOOLCHAIN_DIR:-$HOME/rtk-toolchain}"
+
+# --- 1. Resolve / fetch the SDK (pin comes from ameba_sdk.mk, single source) 
--
+
+if [ -n "$AMEBA_SDK" ] && [ -d "$AMEBA_SDK/component/soc" ]; then
+  : # external checkout, use as-is
+else
+  AMEBA_SDK="$AMEBA_COMMON/ameba-rtos"
+  if [ ! -d "$AMEBA_SDK/component/soc" ]; then
+    _url=$(sed -n 
's/^[[:space:]]*AMEBA_SDK_URL[[:space:]]*=[[:space:]]*\([^[:space:]]*\).*/\1/p' 
\
+           "$AMEBA_COMMON/ameba_sdk.mk" | head -1)
+    _ver=$(sed -n 
's/^[[:space:]]*AMEBA_SDK_VERSION[[:space:]]*=[[:space:]]*\([0-9a-fA-F]*\).*/\1/p'
 \
+           "$AMEBA_COMMON/ameba_sdk.mk" | head -1)
+    sh "$AMEBA_TOOLS/ameba_fetch_sdk.sh" "$_url" "$_ver" "$AMEBA_SDK" || 
return 1 2>/dev/null || exit 1
+  fi
+fi
+export AMEBA_SDK
+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" 
\
+  || 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")
+_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"
+export GCCVER="${_ver%%.*}"
+
+# --- 3. prebuilts (ninja/cmake) + python venv (SDK env) ----------------------
+
+sh "$AMEBA_TOOLS/ameba_setup_env.sh" "$AMEBA_SDK" "$AMEBA_TOOLCHAIN_DIR" \
+  || return 1 2>/dev/null || exit 1
+
+_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) -----------------------------------------
+
+for _d in "$_venv_bin" "$_prebuilts_bin" "$_asdk_bin"; do
+  [ -n "$_d" ] || continue
+  case ":$PATH:" in
+    *":$_d:"*) ;;
+    *) PATH="$_d:$PATH" ;;
+  esac
+done
+export PATH
+
+echo "ameba: environment ready"
+echo "  AMEBA_SDK = $AMEBA_SDK"
+echo "  asdk      = $_asdk_bin"
+echo "  now build with cmake (source once) or make"

Reply via email to