Skip to content

Commit

Permalink
Merge branch 'feature/compiler_rt_support' into 'master'
Browse files Browse the repository at this point in the history
build: Adds support for compiler-rt in Clang toolchain

See merge request espressif/esp-idf!21213
  • Loading branch information
gerekon committed Jun 8, 2023
2 parents f875978 + c9b7748 commit d4e1935
Show file tree
Hide file tree
Showing 23 changed files with 146 additions and 40 deletions.
9 changes: 9 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ cache:

source ./export.sh

# Custom clang
if [[ ! -z "$CI_CLANG_DISTRO_URL" ]]; then
echo "Using custom clang from ${CI_CLANG_DISTRO_URL}"
wget $CI_CLANG_DISTRO_URL
ARCH_NAME=$(basename $CI_CLANG_DISTRO_URL)
tar -x -f $ARCH_NAME
export PATH=$PWD/esp-clang/bin:$PATH
fi

# Custom OpenOCD
if [[ ! -z "$OOCD_DISTRO_URL" && "$CI_JOB_STAGE" == "target_test" ]]; then
echo "Using custom OpenOCD from ${OOCD_DISTRO_URL}"
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
list(APPEND compile_options "-Wno-c2x-extensions")
# warning on xMPU_SETTINGS for esp32s2 has size 0 for C and 1 for C++
list(APPEND compile_options "-Wno-extern-c-compat")
# warning: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1
list(APPEND compile_options "-Wno-single-bit-bitfield-constant-conversion")
endif()
# More warnings may exist in unit tests and example projects.

Expand Down Expand Up @@ -222,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,
Expand Down
33 changes: 33 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
6 changes: 6 additions & 0 deletions components/app_trace/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ idf_component_register(SRCS "${srcs}"
idf_component_get_property(app_trace app_trace COMPONENT_LIB)

if(CONFIG_APPTRACE_GCOV_ENABLE)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
# Coverage info is not supported when clang is used
# TODO: LLVM-214
message(FATAL_ERROR "Coverage info is not supported when building with Clang!")
endif()

# The original Gcov library from toolchain will be objcopy with symbols redefinitions (see file gcov/io_sym.map).
# This needs because ESP has no file-system onboard, and redefined functions solves this problem and transmits
# output file to host PC.
Expand Down
2 changes: 2 additions & 0 deletions components/bootloader/subproject/main/ld/esp32/bootloader.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*)
Expand Down
4 changes: 2 additions & 2 deletions components/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
Expand Down
22 changes: 4 additions & 18 deletions components/efuse/esp32h2/esp_efuse_utility.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -115,24 +115,14 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
hal_memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
}
unsigned r_data_len = (range_read_addr_blocks[num_block].end - range_read_addr_blocks[num_block].start) + sizeof(uint32_t);
unsigned data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t);
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len);

uint32_t backup_write_data[8 + 3]; // 8 words are data and 3 words are RS coding data
#pragma GCC diagnostic push
#if __GNUC__ >= 11
#pragma GCC diagnostic ignored "-Wstringop-overread"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data));
#pragma GCC diagnostic pop
hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data));
int repeat_burn_op = 1;
bool correct_written_data;
bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block);
Expand Down Expand Up @@ -161,11 +151,7 @@ esp_err_t esp_efuse_utility_burn_chip(void)
correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len);
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
}

} while ((!correct_written_data || coding_error_occurred) && repeat_burn_op++ < 3);
Expand Down
2 changes: 1 addition & 1 deletion components/newlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
9 changes: 9 additions & 0 deletions components/newlib/system_libs.lf
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions tools/ci/check_ldgen_mapping_exceptions.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
libc
sha256_coredump
gcc
clang_rt_builtins
2 changes: 2 additions & 0 deletions tools/cmake/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions tools/cmake/kconfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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}
Expand All @@ -218,13 +220,15 @@ 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
# additional run of kconfgen esures that the deprecated options will be inserted into sdkconfig (for backward
# compatibility)
COMMAND ${kconfgen_basecommand}
--env "IDF_TARGET=${idf_target}"
--env "IDF_TOOLCHAIN=${idf_toolchain}"
--env "IDF_ENV_FPGA=${idf_env_fpga}"
--output config ${sdkconfig}
)
Expand Down
32 changes: 32 additions & 0 deletions tools/cmake/toolchain-clang-esp32h4.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
include($ENV{IDF_PATH}/tools/cmake/utilities.cmake)

set(CMAKE_SYSTEM_NAME Generic)

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)

set(CMAKE_AR llvm-ar)
set(CMAKE_RANLIB llvm-ranlib)
set(CMAKE_OBJDUMP riscv32-esp-elf-objdump)

remove_duplicated_flags("--target=riscv32-esp-elf -march=rv32imc -mabi=ilp32 \
${CMAKE_C_FLAGS}"
UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}"
CACHE STRING "C Compiler Base Flags"
FORCE)

remove_duplicated_flags("--target=riscv32-esp-elf -march=rv32imc -mabi=ilp32 \
${CMAKE_CXX_FLAGS}"
UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}"
CACHE STRING "C++ Compiler Base Flags"
FORCE)

remove_duplicated_flags("--target=riscv32-esp-elf -march=rv32imc -mabi=ilp32 \
${CMAKE_ASM_FLAGS}"
UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}"
CACHE STRING "Assembler Base Flags"
FORCE)
1 change: 1 addition & 0 deletions tools/kconfig_new/config.env.in
Original file line number Diff line number Diff line change
Expand Up @@ -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}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_COMPILER_RT_LIB_CLANGRT=y
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_COMPILER_RT_LIB_GCCLIB=y
Loading

0 comments on commit d4e1935

Please sign in to comment.