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

Reply via email to