From feedef9d3ee4764db32daf282477d54525e53f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Wed, 27 May 2026 11:17:19 -0400 Subject: [PATCH] cmake: rename rv32 toolchain file to riscv32-unknown-elf-rv32imc.cmake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename cmake/riscv64-gcc-rv32imc.cmake to the accurate name cmake/riscv32-unknown-elf-rv32imc.cmake and switch the compiler from riscv64-unknown-elf-gcc to riscv32-unknown-elf-gcc. The riscv-collab riscv64-elf toolchain has no rv32 multilib and will fail to link soft-float and integer helpers (__clzsi2, __muldf3, etc.) when building for -march=rv32imc_zicsr -mabi=ilp32. The dedicated riscv32-unknown-elf-gcc (riscv-collab riscv32-elf release, installed to /opt/riscv by scripts/install_riscv.sh) ships the correct native rv32/ilp32 libgcc — analogous to arm-none-eabi-gcc for Cortex-M. The old filename is kept as a two-line compatibility alias that includes the new file, so any out-of-tree users who hardcode the old path still work. Also update: - core_v_mcu/build.sh: reference new cmake filename - core_v_mcu/README.md: update prerequisites table and toolchain docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- cmake/riscv32-unknown-elf-rv32imc.cmake | 69 ++++++++++++++++ cmake/riscv64-gcc-rv32imc.cmake | 78 +------------------ .../gnu/example_build/core_v_mcu/README.md | 27 ++++--- .../gnu/example_build/core_v_mcu/build.sh | 2 +- 4 files changed, 87 insertions(+), 89 deletions(-) create mode 100644 cmake/riscv32-unknown-elf-rv32imc.cmake diff --git a/cmake/riscv32-unknown-elf-rv32imc.cmake b/cmake/riscv32-unknown-elf-rv32imc.cmake new file mode 100644 index 000000000..7e9356898 --- /dev/null +++ b/cmake/riscv32-unknown-elf-rv32imc.cmake @@ -0,0 +1,69 @@ +# /*************************************************************************** +# * Copyright (C) 2026 Eclipse ThreadX contributors +# * +# * This program and the accompanying materials are made available under the +# * terms of the MIT License which is available at +# * https://opensource.org/licenses/MIT. +# * +# * SPDX-License-Identifier: MIT +# ***************************************************************************/ + +# CMake toolchain file for CORE-V MCU (CV32E40P, RV32IMC) +# +# Uses the dedicated riscv32-unknown-elf-gcc bare-metal toolchain from +# riscv-collab (riscv32-elf-ubuntu-24.04-gcc.tar.xz, installs to /opt/riscv). +# This is the correct toolchain for RV32 bare-metal targets — analogous to +# arm-none-eabi-gcc for Cortex-M. It ships a native rv32/ilp32 libgcc with +# all soft-float and integer helpers (__clzsi2, __muldf3, etc.) built for the +# correct ABI. +# +# Do NOT use riscv64-unknown-elf-gcc for this target: the riscv-collab +# riscv64-elf toolchain is built without rv32 multilib and will produce +# missing-symbol linker errors with -nodefaultlibs. +# +# Install both toolchains with: bash scripts/install_riscv.sh +# +# Target ISA : rv32imc_zicsr (integer, multiply, compressed, Zicsr) +# ABI : ilp32 (32-bit int/long/ptr, no hardware FP) +# Code model : medlow (addresses in [0, 2 GiB)) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR riscv) + +set(THREADX_ARCH "risc-v32") +set(THREADX_TOOLCHAIN "gnu") + +set(ARCH_FLAGS "-march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow") +set(CFLAGS "${ARCH_FLAGS}") +set(ASFLAGS "${ARCH_FLAGS}") +set(LDFLAGS "${ARCH_FLAGS}") + +# Dedicated riscv32 bare-metal toolchain (riscv-collab riscv32-elf release). +set(CMAKE_C_COMPILER riscv32-unknown-elf-gcc) +set(CMAKE_CXX_COMPILER riscv32-unknown-elf-g++) +set(AS riscv32-unknown-elf-as) +set(AR riscv32-unknown-elf-ar) +set(OBJCOPY riscv32-unknown-elf-objcopy) +set(OBJDUMP riscv32-unknown-elf-objdump) +set(SIZE riscv32-unknown-elf-size) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Use static library for compiler feature probing (no linker script yet) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_FLAGS "${CFLAGS}" CACHE INTERNAL "c compiler flags") +set(CMAKE_CXX_FLAGS "${CFLAGS}" CACHE INTERNAL "cxx compiler flags") +set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags") +set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags") + +set(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug flags") +set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug flags") +set(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug flags") + +set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "c release flags") +set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "cxx release flags") +set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release flags") diff --git a/cmake/riscv64-gcc-rv32imc.cmake b/cmake/riscv64-gcc-rv32imc.cmake index aa19b6245..d3d50115d 100644 --- a/cmake/riscv64-gcc-rv32imc.cmake +++ b/cmake/riscv64-gcc-rv32imc.cmake @@ -1,76 +1,2 @@ -# /*************************************************************************** -# * Copyright (C) 2026 Eclipse ThreadX contributors -# * -# * This program and the accompanying materials are made available under the -# * terms of the MIT License which is available at -# * https://opensource.org/licenses/MIT. -# * -# * AI Disclosure: This file was largely AI-generated by Copilot (Sonnet 4.6). -# * The AI-generated portions may be considered public domain (CC0-1.0) -# * and not subject to the project's licence. The human contributor has -# * reviewed and verified that the code is correct. -# * -# * SPDX-License-Identifier: MIT and CC0-1.0 -# ***************************************************************************/ - -# CMake toolchain file for CORE-V MCU (CV32E40P, RV32IMC) -# -# Uses the riscv64-unknown-elf-gcc cross-compiler to produce rv32imc/ilp32 -# bare-metal firmware. The riscv-collab toolchain (installed to /opt/riscv by -# scripts/install_riscv.sh) is used by default. The Ubuntu package -# gcc-riscv64-unknown-elf also works and can be installed via install_deps.sh. -# -# Note: the riscv-collab toolchain is built without multilib, so it does not -# ship an rv32/ilp32 libgcc. The CORE-V MCU BSP provides a weak __clzsi2 -# fallback in bsp/clz.c to satisfy any __builtin_clz() calls without relying -# on libgcc. -# -# Target ISA : rv32imc_zicsr (integer, multiply, compressed, Zicsr) -# ABI : ilp32 (32-bit int/long/ptr, no hardware FP) -# Code model : medlow (addresses in [0, 2 GiB)) - -set(CMAKE_SYSTEM_NAME Generic) -set(CMAKE_SYSTEM_PROCESSOR riscv) - -set(THREADX_ARCH "risc-v32") -set(THREADX_TOOLCHAIN "gnu") - -set(ARCH_FLAGS "-march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow") -set(CFLAGS "${ARCH_FLAGS}") -set(ASFLAGS "${ARCH_FLAGS}") -set(LDFLAGS "${ARCH_FLAGS}") - -# Toolchain binaries: riscv64-unknown-elf-gcc cross-compiler. -# The riscv-collab toolchain (scripts/install_riscv.sh → /opt/riscv/bin) is the -# preferred choice. The Ubuntu package (gcc-riscv64-unknown-elf, install via -# install_deps.sh) is also supported. Both are searched via PATH so whichever -# comes first is used; ensure /opt/riscv/bin precedes /usr/bin if you want the -# riscv-collab toolchain. -set(CMAKE_C_COMPILER riscv64-unknown-elf-gcc) -set(CMAKE_CXX_COMPILER riscv64-unknown-elf-g++) -set(AS riscv64-unknown-elf-as) -set(AR riscv64-unknown-elf-ar) -set(OBJCOPY riscv64-unknown-elf-objcopy) -set(OBJDUMP riscv64-unknown-elf-objdump) -set(SIZE riscv64-unknown-elf-size) - -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - -# Use static library for compiler feature probing (no linker script yet) -set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) - -set(CMAKE_C_FLAGS "${CFLAGS}" CACHE INTERNAL "c compiler flags") -set(CMAKE_CXX_FLAGS "${CFLAGS}" CACHE INTERNAL "cxx compiler flags") -set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags") -set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags") - -set(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug flags") -set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug flags") -set(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug flags") - -set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "c release flags") -set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "cxx release flags") -set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release flags") +# This file is a compatibility alias. Use riscv32-unknown-elf-rv32imc.cmake. +include(${CMAKE_CURRENT_LIST_DIR}/riscv32-unknown-elf-rv32imc.cmake) diff --git a/ports/risc-v32/gnu/example_build/core_v_mcu/README.md b/ports/risc-v32/gnu/example_build/core_v_mcu/README.md index d94759d00..d2b8a8442 100644 --- a/ports/risc-v32/gnu/example_build/core_v_mcu/README.md +++ b/ports/risc-v32/gnu/example_build/core_v_mcu/README.md @@ -57,15 +57,18 @@ Or install individually: | Tool | Minimum version | Notes | |------|----------------|-------| -| `riscv64-unknown-elf-gcc` | 13.x | `apt install gcc-riscv64-unknown-elf binutils-riscv64-unknown-elf` | +| `riscv32-unknown-elf-gcc` | 15.x | riscv-collab `riscv32-elf` release — run `bash scripts/install_riscv.sh` | | CMake | 3.15 | `apt install cmake` | | Ninja | 1.10 | `apt install ninja-build` | | OpenOCD | 0.12 | `apt install openocd` | -| GDB | any multiarch | `apt install gdb-multiarch` — Ubuntu does not ship `riscv64-unknown-elf-gdb` | +| GDB | any multiarch | `apt install gdb-multiarch` — Ubuntu does not ship `riscv32-unknown-elf-gdb` | -> **Note:** There is no `riscv32-unknown-elf-gcc` package required. The -> `riscv64-unknown-elf-gcc` compiler generates RV32 code when passed -> `-march=rv32imc_zicsr -mabi=ilp32`, as configured by the toolchain file. +> **Note:** Use the dedicated `riscv32-unknown-elf-gcc` bare-metal toolchain +> (riscv-collab `riscv32-elf` release, installs to `/opt/riscv`). This is +> the RV32 equivalent of `arm-none-eabi-gcc` and ships a native rv32/ilp32 +> libgcc with all required soft-float and integer helpers. Do **not** use +> `riscv64-unknown-elf-gcc` — the riscv-collab riscv64-elf toolchain has no +> rv32 multilib and will produce missing-symbol linker errors. --- @@ -221,19 +224,19 @@ build/demo_threadx.map — linker map ```bash THREADX_ROOT=$(realpath ../../../../..) cmake -B build -G Ninja \ - -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake" \ + -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \ . cmake --build build ``` ### Toolchain file -`${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake` sets: +`${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake` sets: ``` -CMAKE_C_COMPILER riscv64-unknown-elf-gcc -CMAKE_ASM_COMPILER riscv64-unknown-elf-gcc -CMAKE_OBJCOPY riscv64-unknown-elf-objcopy +CMAKE_C_COMPILER riscv32-unknown-elf-gcc +CMAKE_ASM_COMPILER riscv32-unknown-elf-gcc +CMAKE_OBJCOPY riscv32-unknown-elf-objcopy CMAKE_C_FLAGS -march=rv32imc_zicsr -mabi=ilp32 -mcmodel=medlow ``` @@ -285,7 +288,7 @@ port 3333 (GDB) and 4444 (telnet). In a second terminal: ```bash -riscv64-unknown-elf-gdb --command=gdb_init +riscv32-unknown-elf-gdb --command=gdb_init ``` `gdb_init` connects to OpenOCD, loads the ELF, sets a breakpoint at `main`, and @@ -485,7 +488,7 @@ bash deploy.sh --debug ``` The script starts OpenOCD in the background, waits for it to become ready, -then drives `riscv64-unknown-elf-gdb` to load the ELF. OpenOCD is always +then drives `riscv32-unknown-elf-gdb` to load the ELF. OpenOCD is always stopped on exit (including Ctrl-C). --- diff --git a/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh b/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh index fe78a8e64..c2ccfc559 100755 --- a/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh +++ b/ports/risc-v32/gnu/example_build/core_v_mcu/build.sh @@ -4,6 +4,6 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" THREADX_ROOT="${SCRIPT_DIR}/../../../../.." cmake -B "${SCRIPT_DIR}/build" \ -G Ninja \ - -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv64-gcc-rv32imc.cmake" \ + -DCMAKE_TOOLCHAIN_FILE="${THREADX_ROOT}/cmake/riscv32-unknown-elf-rv32imc.cmake" \ "${SCRIPT_DIR}" cmake --build "${SCRIPT_DIR}/build"