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 <anchao@lixiang.com>
This commit is contained in:
chao an 2024-04-18 14:01:18 +08:00 committed by Xiang Xiao
parent 55e3cf7e2d
commit e863e3dd37
5 changed files with 155 additions and 62 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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_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)
if(CONFIG_LTO_FULL)
add_compile_options(-flto)
if(${CONFIG_RISCV_TOOLCHAIN} STREQUAL "GNU_RVG")
# 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()

View File

@ -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))