espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.34k stars 7.2k forks source link

Clang: Empty app_main() linking fails if set CONFIG_COMPILER_CXX_EXCEPTIONS=y (IDFGH-13452) #14358

Open denizzzka opened 1 month ago

denizzzka commented 1 month ago

Answers checklist.

IDF version.

~maser (8e4454b28)

Operating System used.

Linux

How did you build your project?

Command line with CMake

If you are using Windows, please specify command line type.

None

What is the expected behavior?

Successful compilation

What is the actual behavior?

Linking fails with errors related to libunwind:

/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: esp-idf/esp_system/libesp_system.a(startup.c.obj): in function `do_global_ctors':
/home/denizzz/Dev/Aeth/Espressif_IDE/esp-idf-v5.2.1/components/esp_system/startup.c:88:(.text.start_cpu0_default+0x30): undefined reference to `__register_frame_info'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_globals.o): in function `.LVL7':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_globals.cc:90:(.text._ZL15eh_globals_dtorPv+0x28): undefined reference to `_Unwind_DeleteException'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_personality.o): in function `.L0 ':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:114:(.text._ZL21base_of_encoded_valuehP15_Unwind_Context+0x48): undefined reference to `_Unwind_GetTextRelBase'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_personality.o): in function `base_of_encoded_value':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:116:(.text._ZL21base_of_encoded_valuehP15_Unwind_Context+0x50): undefined reference to `_Unwind_GetDataRelBase'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:118:(.text._ZL21base_of_encoded_valuehP15_Unwind_Context+0x58): undefined reference to `_Unwind_GetRegionStart'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_personality.o): in function `.L0 ':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:55:(.text._ZL17parse_lsda_headerP15_Unwind_ContextPKhP16lsda_header_info+0x14): undefined reference to `_Unwind_GetRegionStart'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:681:(.text.__gxx_personality_v0+0x86): undefined reference to `_Unwind_GetLanguageSpecificData'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_personality.o): in function `__gxx_personality_v0':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:455:(.text.__gxx_personality_v0+0xce): undefined reference to `_Unwind_GetIPInfo'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:680:(.text.__gxx_personality_v0+0x25a): undefined reference to `_Unwind_SetGR'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:688:(.text.__gxx_personality_v0+0x268): undefined reference to `_Unwind_SetGR'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:692:(.text.__gxx_personality_v0+0x274): undefined reference to `_Unwind_SetIP'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(eh_throw.o): in function `.L0 ':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:93:(.text.__cxa_throw+0x2a): undefined reference to `_Unwind_RaiseException'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(functexcept.o): in function `std::__throw_logic_error(char const*)':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/src/c++11/functexcept.cc:70:(.text.unlikely._ZSt19__throw_logic_errorPKc+0x36): undefined reference to `_Unwind_Resume'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(functexcept.o): in function `std::__throw_length_error(char const*)':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/src/c++11/functexcept.cc:82:(.text.unlikely._ZSt20__throw_length_errorPKc+0x36): undefined reference to `_Unwind_Resume'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(functexcept.o): in function `std::__throw_out_of_range(char const*)':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/src/c++11/functexcept.cc:86:(.text.unlikely._ZSt20__throw_out_of_rangePKc+0x36): undefined reference to `_Unwind_Resume'
/home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/riscv32-esp-elf-clang-ld: /home/denizzz/.espressif/tools/esp-clang/esp-17.0.1_20240419/esp-clang/bin/../lib/clang-runtimes/riscv32-esp-unknown-elf/rv32imc-zicsr-zifencei_ilp32_no-rtti/lib/libstdc++.a(cow-stdexcept.o): in function `std::logic_error::logic_error(char const*)':
/builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/gcc/libstdc++-v3/src/c++11/cow-stdexcept.cc:87:(.text._ZNSt11logic_errorC2EPKc+0x26): undefined reference to `_Unwind_Resume'
clang++: error: ld command failed with exit code 1 (use -v to see invocation)

Steps to reproduce.

  1. install Clang:

    idf_tools.py install esp-clang
  2. Use any project

3 . Add to sdkconfig.defaults in the project root:

CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_ESP_SYSTEM_USE_EH_FRAME=y
  1. Run build:
    idf.py --build-dir=builddir -D IDF_TOOLCHAIN=clang -D CMAKE_BUILD_TYPE=Debug set-target esp32c3 build

Build or installation Logs.

No response

More Information.

Without -D IDF_TOOLCHAIN=clang build works as expected

cristianfunes79 commented 4 weeks ago

I think steps are wrong, you're installing esp-clang in step 1 but then in step 4 you're using clang instead of esp-clang. Following your steps but changing step 4 by esp-clang works for me on cxx/pthread example:

idf.py --build-dir=builddir -D IDF_TOOLCHAIN=esp-clang -D CMAKE_BUILD_TYPE=Debug set-target esp32c3 build

path:

esp-idf/examples/cxx/pthread
denizzzka commented 4 weeks ago

@cristianfunes79 thank you very much!

igrr commented 4 weeks ago

Actually the steps are not wrong, IDF_TOOLCHAIN=clang switches to clang-based toolchain in IDF. If you specify esp-clang, I think the value is simply ignored and you get a GCC toolchain by default (and no linking error, since we don't have this bug with GCC-based toolchain)

https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/tools/cmake/targets.cmake#L149

denizzzka commented 4 weeks ago

Indeed, build script began to use gcc, but nothing was broken

Clang support is important for me because project will be linked with 3-rd party library built by LLVM

igrr commented 4 weeks ago

@denizzzka technically, you shouldn't need to build the whole project with Clang to do that. The details will depend on how you are building that library and whether it depends on Clang's libc++, but generally you could use ExternalProject_Add to build your library and then link it to the rest of your app (which could be built with GCC).

denizzzka commented 2 weeks ago

technically, you shouldn't need to build the whole project with Clang to do that.

LLVM and gcc compillers sometimes differently treating ABI and stack unwinding. (For example, right now I run into different format of passing struct containing 3 bytes from LLVM to gcc.)

igrr commented 2 weeks ago

@denizzzka if you can report the details of this struct ABI mismatch issue over at https://github.com/espressif/llvm-project/issues, that would be very much appreciated!

We do intend to use some libraries compiled with GCC (e.g. Wi-Fi driver closed-source libraries) in applications built with LLVM, so we definitely need to fix this type of issues.

As for the stack unwinding, do you have any example of such incompatibility?

denizzzka commented 2 weeks ago

@denizzzka if you can report the details of this struct ABI mismatch issue over at https://github.com/espressif/llvm-project/issues, that would be very much appreciated!

Ok. I'm still researching this issue

As for the stack unwinding, do you have any example of such incompatibility?

It was happened on ARM (i.e. not related to ESP): TType value (libgcc/config/arm/unwind-arm.h) was different for bare-metal targets on LLVM and libgcc. On LLVM it was same as for Linux:

TType = DW_EH_PE_pcrel | DW_EH_PE_indirect;

but recently (~year) it was changed to same as in GNU:

TType = DW_EH_PE_pcrel;

I.e., this is already fixed, but I remember that I had to search for this problem twice - initially and then after they fixed it :-)