This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e863e3dd37 arch/risc-v: add LLVM clang support
e863e3dd37 is described below
commit e863e3dd378c9ba3d5774f9491189e5a991474b0
Author: chao an <[email protected]>
AuthorDate: Thu Apr 18 14:01:18 2024 +0800
arch/risc-v: add LLVM clang support
Verified on LLVM-Metal:
$ riscv64-unknown-elf-clang --version
(LLVM-Metal 15.9.0-2023.03.0) clang version 15.9.0
Target: riscv64-unknown-unknown-elf
Thread model: posix
Signed-off-by: chao an <[email protected]>
---
arch/arm/src/cmake/Toolchain.cmake | 4 +-
arch/risc-v/Kconfig | 4 ++
arch/risc-v/src/Makefile | 6 +-
arch/risc-v/src/cmake/Toolchain.cmake | 100 +++++++++++++++++++++-----------
arch/risc-v/src/common/Toolchain.defs | 105 ++++++++++++++++++++++++++--------
5 files changed, 156 insertions(+), 63 deletions(-)
diff --git a/arch/arm/src/cmake/Toolchain.cmake
b/arch/arm/src/cmake/Toolchain.cmake
index 0ba3fdf239..41d2c89dd6 100644
--- a/arch/arm/src/cmake/Toolchain.cmake
+++ b/arch/arm/src/cmake/Toolchain.cmake
@@ -67,8 +67,8 @@ else()
set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN_PREFIX})
set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN_PREFIX})
- set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
- set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+ set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+ set(CMAKE_C_COMPILER ${CMAKE_ASM_COMPILER})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-strip --strip-unneeded)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy)
diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index 6a6d3f9a39..cf97f0c306 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -498,6 +498,10 @@ config RISCV_TOOLCHAIN_GNU_RV32
This option should work for any modern GNU toolchain (GCC 5.2
or newer)
configured for riscv32-unknown-elf.
+config RISCV_TOOLCHAIN_CLANG
+ bool "LLVM Clang toolchain"
+ select ARCH_TOOLCHAIN_CLANG
+
endchoice # Toolchain Selection
config RISCV_SEMIHOSTING_HOSTFS
diff --git a/arch/risc-v/src/Makefile b/arch/risc-v/src/Makefile
index 2333c44cbf..41df61e21c 100644
--- a/arch/risc-v/src/Makefile
+++ b/arch/risc-v/src/Makefile
@@ -107,11 +107,13 @@ ifeq ($(LD),$(CC))
# -fstack-protector-explicit
STRIPCFLAGS = $(filter -fstack-protector%,$(CFLAGS))
endif
+ LDENTRY ?= -Wl,--entry=__start
LDSTARTGROUP ?= -Wl,--start-group
LDENDGROUP ?= -Wl,--end-group
LDFLAGS := $(addprefix -Xlinker ,$(LDFLAGS))
LDFLAGS += $(filter-out $(STRIPCFLAGS),$(CFLAGS))
else
+ LDENTRY ?= --entry=__start
LDSTARTGROUP ?= --start-group
LDENDGROUP ?= --end-group
endif
@@ -180,7 +182,7 @@ define LINK_ALLSYMS_KASAN
$(Q) $(TOPDIR)/tools/kasan_global.py -e $(NUTTX) -o kasan_globals.tmp
$(Q) $(call COMPILE, kasan_globals.tmp, kasan_globals$(OBJEXT)
-fno-sanitize=kernel-address, -x c)
$(Q) $(call DELFILE, kasan_globals.tmp))
- $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \
+ $(Q) $(LD) $(LDENTRY) $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \
-o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \
$(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP)
endef
@@ -191,7 +193,7 @@ $(addsuffix .tmp,$(ARCHSCRIPT)): $(ARCHSCRIPT)
nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) $(addsuffix
.tmp,$(ARCHSCRIPT))
$(Q) echo "LD: nuttx"
ifeq ($(CONFIG_ALLSYMS)$(CONFIG_MM_KASAN_GLOBAL),)
- $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \
+ $(Q) $(LD) $(LDENTRY) $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \
-o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \
$(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP)
else
diff --git a/arch/risc-v/src/cmake/Toolchain.cmake
b/arch/risc-v/src/cmake/Toolchain.cmake
index f25efc04a7..e475238d53 100644
--- a/arch/risc-v/src/cmake/Toolchain.cmake
+++ b/arch/risc-v/src/cmake/Toolchain.cmake
@@ -24,21 +24,28 @@ set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
-if(CONFIG_RISCV_TOOLCHAIN_GNU_RV32 OR CONFIG_RISCV_TOOLCHAIN_GNU_RV64)
+if(CONFIG_RISCV_TOOLCHAIN_GNU_RV32
+ OR CONFIG_RISCV_TOOLCHAIN_GNU_RV64
+ OR CONFIG_RISCV_TOOLCHAIN_CLANG)
if(NOT CONFIG_RISCV_TOOLCHAIN)
set(CONFIG_RISCV_TOOLCHAIN GNU_RVG)
endif()
endif()
# Default toolchain
-find_program(RV_COMPILER riscv-none-elf-gcc)
-if(RV_COMPILER)
- set(TOOLCHAIN_PREFIX riscv-none-elf)
+
+if(CONFIG_ARCH_TOOLCHAIN_CLANG)
+ set(TOOLCHAIN_PREFIX riscv64-unknown-elf)
else()
- if(CONFIG_RISCV_TOOLCHAIN_GNU_RV32)
- set(TOOLCHAIN_PREFIX riscv32-unknown-elf)
+ find_program(RV_COMPILER riscv-none-elf-gcc)
+ if(RV_COMPILER)
+ set(TOOLCHAIN_PREFIX riscv-none-elf)
else()
- set(TOOLCHAIN_PREFIX riscv64-unknown-elf)
+ if(CONFIG_RISCV_TOOLCHAIN_GNU_RV32)
+ set(TOOLCHAIN_PREFIX riscv32-unknown-elf)
+ else()
+ set(TOOLCHAIN_PREFIX riscv64-unknown-elf)
+ endif()
endif()
endif()
@@ -46,26 +53,56 @@ set(CMAKE_LIBRARY_ARCHITECTURE ${TOOLCHAIN_PREFIX})
set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN_PREFIX})
set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN_PREFIX})
-set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
-set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
-set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
-set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-strip --strip-unneeded)
-set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy)
-set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump)
-set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-gcc)
-set(CMAKE_LD ${TOOLCHAIN_PREFIX}-ld)
-set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar)
-set(CMAKE_NM ${TOOLCHAIN_PREFIX}-nm)
-set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-gcc-ranlib)
-
-if(CONFIG_LTO_FULL)
- add_compile_options(-flto)
- if(${CONFIG_RISCV_TOOLCHAIN} STREQUAL "GNU_RVG")
+if(CONFIG_ARCH_TOOLCHAIN_CLANG)
+ set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-clang)
+ set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang)
+ set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++)
+ set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-llvm-strip --strip-unneeded)
+ set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-llvm-objcopy)
+ set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-llvm-objdump)
+ set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-ld)
+ set(CMAKE_LD ${TOOLCHAIN_PREFIX}-ld)
+ set(CMAKE_AR ${TOOLCHAIN_PREFIX}-llvm-ar)
+ set(CMAKE_NM ${TOOLCHAIN_PREFIX}-llvm-nm)
+ set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-llvm-ranlib)
+
+ # Since the no_builtin attribute is not fully supported on Clang disable the
+ # built-in functions, refer:
+ # https://github.com/apache/incubator-nuttx/pull/5971
+
+ add_compile_options(-fno-builtin)
+else()
+ set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+ set(CMAKE_C_COMPILER ${CMAKE_ASM_COMPILER})
+ set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+ set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-strip --strip-unneeded)
+ set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy)
+ set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump)
+
+ if(CONFIG_LTO_FULL AND CONFIG_ARCH_TOOLCHAIN_GNU)
+ set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_LD ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_AR ${TOOLCHAIN_PREFIX}-gcc-ar)
set(CMAKE_NM ${TOOLCHAIN_PREFIX}-gcc-nm)
- add_compile_options(-fuse-linker-plugin)
+ set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-gcc-ranlib)
+ else()
+ set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-ld)
+ set(CMAKE_LD ${TOOLCHAIN_PREFIX}-ld)
+ set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar)
+ set(CMAKE_NM ${TOOLCHAIN_PREFIX}-nm)
+ set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-ranlib)
+ endif()
+endif()
+
+# Link Time Optimization
+
+if(CONFIG_LTO_THIN)
+ add_compile_options(-flto=thin)
+elseif(CONFIG_LTO_FULL)
+ add_compile_options(-flto)
+ if(CONFIG_ARCH_TOOLCHAIN_GNU)
add_compile_options(-fno-builtin)
+ add_compile_options(-fuse-linker-plugin)
endif()
endif()
@@ -78,7 +115,11 @@ set(CMAKE_ASM_ARCHIVE_CREATE "<CMAKE_AR> rcs <TARGET>
<LINK_FLAGS> <OBJECTS>")
if(CONFIG_DEBUG_CUSTOMOPT)
add_compile_options(${CONFIG_DEBUG_OPTLEVEL})
elseif(CONFIG_DEBUG_FULLOPT)
- add_compile_options(-Os)
+ if(CONFIG_ARCH_TOOLCHAIN_CLANG)
+ add_compile_options(-Oz)
+ else()
+ add_compile_options(-Os)
+ endif()
endif()
if(NOT CONFIG_DEBUG_NOOPT)
@@ -180,15 +221,6 @@ endif()
# Generic GNU RVG toolchain
if(${CONFIG_RISCV_TOOLCHAIN} STREQUAL GNU_RVG)
- execute_process(COMMAND ${TOOLCHAIN_PREFIX}-gcc --version
- OUTPUT_VARIABLE GCC_VERSION_OUTPUT)
- string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" GCC_VERSION
- ${GCC_VERSION_OUTPUT})
- string(REGEX MATCH "^[0-9]+" GCC_VERSION_MAJOR ${GCC_VERSION})
- if(GCC_VERSION GREATER_EQUAL 12)
- set(ARCHRVISAZ "_zicsr_zifencei")
- endif()
-
set(ARCHCPUEXTFLAGS i)
if(CONFIG_ARCH_RV_ISA_M)
@@ -227,7 +259,7 @@ if(${CONFIG_RISCV_TOOLCHAIN} STREQUAL GNU_RVG)
"${GCC_VERSION_OUTPUT}")
set(GCCVER ${CMAKE_MATCH_1})
endif()
- if(GCCVER GREATER_EQUAL 12)
+ if(GCCVER GREATER_EQUAL 12 OR CONFIG_ARCH_TOOLCHAIN_CLANG)
set(ARCHCPUEXTFLAGS ${ARCHCPUEXTFLAGS}_zicsr_zifencei)
endif()
endif()
diff --git a/arch/risc-v/src/common/Toolchain.defs
b/arch/risc-v/src/common/Toolchain.defs
index 66d2a7805b..27d3c0c678 100644
--- a/arch/risc-v/src/common/Toolchain.defs
+++ b/arch/risc-v/src/common/Toolchain.defs
@@ -31,6 +31,8 @@ ifeq ($(filter y, $(CONFIG_RISCV_TOOLCHAIN_GNU_RV64)),y)
CONFIG_RISCV_TOOLCHAIN ?= GNU_RVG
else ifeq ($(filter y, $(CONFIG_RISCV_TOOLCHAIN_GNU_RV32)),y)
CONFIG_RISCV_TOOLCHAIN ?= GNU_RVG
+else ifeq ($(filter y, $(CONFIG_RISCV_TOOLCHAIN_CLANG)),y)
+ CONFIG_RISCV_TOOLCHAIN ?= GNU_RVG
endif
#
@@ -48,7 +50,11 @@ endif
ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
ARCHOPTIMIZATION += $(CONFIG_DEBUG_OPTLEVEL)
else ifeq ($(CONFIG_DEBUG_FULLOPT),y)
- ARCHOPTIMIZATION += -Os
+ ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y)
+ ARCHOPTIMIZATION += -Oz
+ else
+ ARCHOPTIMIZATION += -Os
+ endif
endif
ifneq ($(CONFIG_DEBUG_NOOPT),y)
@@ -123,7 +129,8 @@ ifeq ($(CONFIG_DEBUG_OPT_UNUSED_SECTIONS),y)
ARCHOPTIMIZATION += -ffunction-sections -fdata-sections
endif
-LDFLAGS += -nostdlib
+LDFLAGS += -nostdlib
+ARCHOPTIMIZATION += -nostdlib
# Debug link map
@@ -142,13 +149,17 @@ ifeq ($(CONFIG_RISCV_TOOLCHAIN),GNU_RVG)
# Generic GNU RVG toolchain, prefer to use riscv-none-elf-gcc from xPack
# if CROSSDEV is not defined.
- ifeq ($(shell riscv-none-elf-gcc --version > /dev/null 2>&1; echo $$?), 0)
- CROSSDEV ?= riscv-none-elf-
+ ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y)
+ CROSSDEV ?= riscv64-unknown-elf-
else
- ifeq ($(CONFIG_RISCV_TOOLCHAIN_GNU_RV32),y)
- CROSSDEV ?= riscv32-unknown-elf-
+ ifeq ($(shell riscv-none-elf-gcc --version > /dev/null 2>&1; echo $$?), 0)
+ CROSSDEV ?= riscv-none-elf-
else
- CROSSDEV ?= riscv64-unknown-elf-
+ ifeq ($(CONFIG_RISCV_TOOLCHAIN_GNU_RV32),y)
+ CROSSDEV ?= riscv32-unknown-elf-
+ else
+ CROSSDEV ?= riscv64-unknown-elf-
+ endif
endif
endif
@@ -292,34 +303,78 @@ ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
ARCHOPTIMIZATION += -finstrument-functions
endif
+# Link Time Optimization
+
+ifeq ($(CONFIG_LTO_THIN),y)
+ ARCHOPTIMIZATION += -flto=thin
+else ifeq ($(CONFIG_LTO_FULL),y)
+ ARCHOPTIMIZATION += -flto
+ ifeq ($(CONFIG_ARM_TOOLCHAIN_GNU_EABI),y)
+ ARCHOPTIMIZATION += -fuse-linker-plugin
+ endif
+endif
+
+# Clang toolchain
+
+ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y)
+
+ CC = $(CROSSDEV)clang
+ CXX = $(CROSSDEV)clang++
+ CPP = $(CROSSDEV)clang -E -P -x c
+ LD = $(CROSSDEV)clang
+ STRIP = $(CROSSDEV)llvm-strip --strip-unneeded
+ AR = $(CROSSDEV)llvm-ar rcs
+ NM = $(CROSSDEV)llvm-nm
+ OBJCOPY = $(CROSSDEV)llvm-objcopy
+ OBJDUMP = $(CROSSDEV)llvm-objdump
+
+ # Since the no_builtin attribute is not fully supported on Clang
+ # disable the built-in functions, refer:
+ # https://github.com/apache/nuttx/pull/5971
+
+ ARCHOPTIMIZATION += -fno-builtin
+
+ ARCHOPTIMIZATION += -fshort-enums
+
# Default toolchain
-CC = $(CROSSDEV)gcc
-CXX = $(CROSSDEV)g++
-CPP = $(CROSSDEV)gcc -E -P -x c
-STRIP = $(CROSSDEV)strip --strip-unneeded
-OBJCOPY = $(CROSSDEV)objcopy
-OBJDUMP = $(CROSSDEV)objdump
-LD = $(CROSSDEV)ld
-AR = $(CROSSDEV)ar rcs
-NM = $(CROSSDEV)nm
+else
+
+ CC = $(CROSSDEV)gcc
+ CXX = $(CROSSDEV)g++
+ CPP = $(CROSSDEV)gcc -E -P -x c
+ STRIP = $(CROSSDEV)strip --strip-unneeded
+ OBJCOPY = $(CROSSDEV)objcopy
+ OBJDUMP = $(CROSSDEV)objdump
+ LD = $(CROSSDEV)ld
+ AR = $(CROSSDEV)ar rcs
+ NM = $(CROSSDEV)nm
# Link Time Optimization
-ifeq ($(CONFIG_LTO_FULL),y)
- ARCHOPTIMIZATION += -flto
- ifeq ($(CONFIG_RISCV_TOOLCHAIN),GNU_RVG)
- LD := $(CROSSDEV)gcc
- AR := $(CROSSDEV)gcc-ar rcs
- NM := $(CROSSDEV)gcc-nm
- ARCHOPTIMIZATION += -fuse-linker-plugin
- ARCHOPTIMIZATION += -fno-builtin
+ ifeq ($(CONFIG_LTO_FULL),y)
+ ifeq ($(CONFIG_RISCV_TOOLCHAIN),GNU_RVG)
+ LD := $(CROSSDEV)gcc
+ AR := $(CROSSDEV)gcc-ar rcs
+ NM := $(CROSSDEV)gcc-nm
+ ARCHOPTIMIZATION += -fno-builtin
+ endif
endif
+
endif
# Add the builtin library
-EXTRA_LIBS += $(wildcard $(shell $(CC) $(ARCHCPUFLAGS)
--print-libgcc-file-name))
+COMPILER_RT_LIB = $(shell $(CC) $(ARCHCPUFLAGS) --print-libgcc-file-name)
+ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y)
+ ifeq ($(wildcard $(COMPILER_RT_LIB)),)
+ # if "--print-libgcc-file-name" unable to find the correct libgcc PATH
+ # then go ahead and try "--print-file-name"
+ COMPILER_RT_LIB := $(wildcard $(shell $(CC) $(ARCHCPUFLAGS)
--print-file-name $(notdir $(COMPILER_RT_LIB))))
+ endif
+endif
+
+EXTRA_LIBS += $(COMPILER_RT_LIB)
ifeq ($(CONFIG_LIBM_TOOLCHAIN),y)
EXTRA_LIBS += $(wildcard $(shell $(CC) $(ARCHCPUFLAGS)
--print-file-name=libm.a))