Przeglądaj źródła

build: Adds support for Clangs's toolchain compiler-rt

Alexey Gerenkov 3 lat temu
rodzic
commit
e9345bcced

+ 5 - 0
CMakeLists.txt

@@ -224,6 +224,11 @@ endif()
 
 if(CMAKE_C_COMPILER_ID MATCHES "Clang")
     list(APPEND compile_options "-fno-use-cxa-atexit")
+    if(CONFIG_COMPILER_RT_LIB_GCCLIB)
+        list(APPEND link_options "-rtlib=libgcc")
+    elseif(CONFIG_COMPILER_RT_LIB_CLANGRT)
+        list(APPEND link_options "-rtlib=compiler-rt")
+    endif()
 endif()
 
 # For the transition period from 32-bit time_t to 64-bit time_t,

+ 33 - 0
Kconfig

@@ -19,6 +19,18 @@ mainmenu "Espressif IoT Development Framework Configuration"
         bool
         default y if "$(IDF_CI_BUILD)" = "y" || "$(IDF_CI_BUILD)" = 1
 
+    config IDF_TOOLCHAIN
+        # This option records the IDF target when sdkconfig is generated the first time.
+        # It is not updated if environment variable $IDF_TOOLCHAIN changes later, and
+        # the build system is responsible for detecting the mismatch between
+        # CONFIG_IDF_TOOLCHAIN and $IDF_TOOLCHAIN.
+        string
+        default "$IDF_TOOLCHAIN"
+
+    config IDF_TOOLCHAIN_CLANG
+        bool
+        default "y" if IDF_TOOLCHAIN="clang"
+
     config IDF_TARGET_ARCH_RISCV
         bool
         default "n"
@@ -493,6 +505,27 @@ mainmenu "Espressif IoT Development Framework Configuration"
                 If enabled, RTL files will be produced during compilation. These files
                 can be used by other tools, for example to calculate call graphs.
 
+        choice COMPILER_RT_LIB
+            prompt "Compiler runtime library"
+            default COMPILER_RT_LIB_CLANGRT if IDF_TOOLCHAIN_CLANG
+            default COMPILER_RT_LIB_GCCLIB
+            help
+                Select runtime library to be used by compiler.
+                - GCC toolchain supports libgcc only.
+                - Clang allows to choose between libgcc or libclang_rt.
+
+            config COMPILER_RT_LIB_GCCLIB
+                bool "libgcc"
+            config COMPILER_RT_LIB_CLANGRT
+                depends on IDF_TOOLCHAIN_CLANG
+                bool "libclang_rt"
+        endchoice
+
+        config COMPILER_RT_LIB_NAME
+            string
+            default "clang_rt.builtins" if COMPILER_RT_LIB_CLANGRT
+            default "gcc" if COMPILER_RT_LIB_GCCLIB
+
     endmenu # Compiler Options
 
     menu "Component config"

+ 2 - 0
components/bootloader/subproject/main/ld/esp32/bootloader.ld

@@ -42,7 +42,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
      *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32c2/bootloader.ld

@@ -63,7 +63,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
      *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32c3/bootloader.ld

@@ -63,7 +63,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
     *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32c6/bootloader.ld

@@ -60,7 +60,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
     *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32h2/bootloader.ld

@@ -61,7 +61,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
     *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32s2/bootloader.ld

@@ -29,7 +29,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
      *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 0
components/bootloader/subproject/main/ld/esp32s3/bootloader.ld

@@ -64,7 +64,9 @@ SECTIONS
     *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
      *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
     *liblog.a:(.literal .text .literal.* .text.*)
+    /* we use either libgcc or compiler-rt, so put similar entries for them here */
     *libgcc.a:(.literal .text .literal.* .text.*)
+    *libclang_rt.builtins.a:(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
     *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)

+ 2 - 2
components/cxx/CMakeLists.txt

@@ -43,7 +43,7 @@ endif()
 if(CMAKE_C_COMPILER_ID MATCHES "Clang")
     # libstdc++ depends on C library, so it should appear later in link order.
     # Otherwise we get undefined references for esp-clang toolchain.
-    target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ c gcc)
+    target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ c ${CONFIG_COMPILER_RT_LIB_NAME})
 else()
     target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc)
 endif()
@@ -63,7 +63,7 @@ else()
 endif()
 target_link_libraries(${COMPONENT_LIB} PUBLIC stdcpp_pthread)
 add_library(libgcc_cxx INTERFACE)
-target_link_libraries(libgcc_cxx INTERFACE gcc $<TARGET_FILE:${cxx}>)
+target_link_libraries(libgcc_cxx INTERFACE ${CONFIG_COMPILER_RT_LIB_NAME} $<TARGET_FILE:${cxx}>)
 target_link_libraries(${COMPONENT_LIB} PUBLIC libgcc_cxx)
 
 if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS)

+ 1 - 1
components/newlib/CMakeLists.txt

@@ -36,7 +36,7 @@ idf_component_register(SRCS "${srcs}"
 
 # Toolchain libraries require code defined in this component
 idf_component_get_property(newlib newlib COMPONENT_LIB)
-target_link_libraries(${COMPONENT_LIB} INTERFACE c m gcc "$<TARGET_FILE:${newlib}>")
+target_link_libraries(${COMPONENT_LIB} INTERFACE c m ${CONFIG_COMPILER_RT_LIB_NAME} "$<TARGET_FILE:${newlib}>")
 
 set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin)
 

+ 9 - 0
components/newlib/system_libs.lf

@@ -7,6 +7,15 @@ entries:
     if IDF_TARGET_ARCH_RISCV:
         save-restore (noflash)
 
+[mapping:clang_rt_builtins]
+archive: libclang_rt.builtins.a
+entries:
+    if IDF_TARGET_ESP32 = n:
+        _divsf3 (noflash)
+    if IDF_TARGET_ARCH_RISCV:
+        save (noflash)
+        restore (noflash)
+
 [mapping:gcov]
 archive: libgcov.a
 entries:

+ 1 - 0
tools/ci/check_ldgen_mapping_exceptions.txt

@@ -1,3 +1,4 @@
 libc
 sha256_coredump
 gcc
+clang_rt_builtins

+ 2 - 0
tools/cmake/build.cmake

@@ -468,6 +468,8 @@ macro(idf_build_process target)
 
     idf_build_set_property(BOOTLOADER_BUILD "${BOOTLOADER_BUILD}")
 
+    idf_build_set_property(IDF_TOOLCHAIN "${IDF_TOOLCHAIN}")
+
     # Check build target is specified. Since this target corresponds to a component
     # name, the target component is automatically added to the list of common component
     # requirements.

+ 4 - 0
tools/cmake/kconfig.cmake

@@ -94,6 +94,7 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults)
     idf_build_set_property(KCONFIG_PROJBUILDS "${kconfig_projbuilds}")
 
     idf_build_get_property(idf_target IDF_TARGET)
+    idf_build_get_property(idf_toolchain IDF_TOOLCHAIN)
     idf_build_get_property(idf_path IDF_PATH)
     idf_build_get_property(idf_env_fpga __IDF_ENV_FPGA)
 
@@ -209,6 +210,7 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults)
         COMMAND ${prepare_kconfig_files_command}
         COMMAND ${kconfgen_basecommand}
         --env "IDF_TARGET=${idf_target}"
+        --env "IDF_TOOLCHAIN=${idf_toolchain}"
         --env "IDF_ENV_FPGA=${idf_env_fpga}"
         --dont-write-deprecated
         --output config ${sdkconfig}
@@ -218,6 +220,7 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults)
         "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=${kconfigs_projbuild_path}"
         "KCONFIG_CONFIG=${sdkconfig}"
         "IDF_TARGET=${idf_target}"
+        "IDF_TOOLCHAIN=${idf_toolchain}"
         "IDF_ENV_FPGA=${idf_env_fpga}"
         ${MENUCONFIG_CMD} ${root_kconfig}
         USES_TERMINAL
@@ -225,6 +228,7 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults)
         # compatibility)
         COMMAND ${kconfgen_basecommand}
         --env "IDF_TARGET=${idf_target}"
+        --env "IDF_TOOLCHAIN=${idf_toolchain}"
         --env "IDF_ENV_FPGA=${idf_env_fpga}"
         --output config ${sdkconfig}
         )

+ 1 - 0
tools/kconfig_new/config.env.in

@@ -3,6 +3,7 @@
     "COMPONENT_KCONFIGS_PROJBUILD": "${kconfig_projbuilds}",
     "COMPONENT_SDKCONFIG_RENAMES": "${sdkconfig_renames}",
     "IDF_TARGET": "${idf_target}",
+    "IDF_TOOLCHAIN": "${idf_toolchain}",
     "IDF_ENV_FPGA": "${idf_env_fpga}",
     "IDF_PATH": "${idf_path}",
     "COMPONENT_KCONFIGS_SOURCE_FILE": "${kconfigs_path}",

+ 1 - 0
tools/test_apps/system/cxx_pthread_bluetooth/sdkconfig.ci.clang_libclang_rt

@@ -0,0 +1 @@
+CONFIG_COMPILER_RT_LIB_CLANGRT=y

+ 1 - 0
tools/test_apps/system/cxx_pthread_bluetooth/sdkconfig.ci.clang_libgcc

@@ -0,0 +1 @@
+CONFIG_COMPILER_RT_LIB_GCCLIB=y