espressif / esp-idf

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

Recent GCC v14 conflicts with stdatomic.h from the xtensa toolchain (esp-13.2.0_20240305) (IDFGH-13033) #13979

Open M-Bab opened 1 month ago

M-Bab commented 1 month ago

Answers checklist.

General issue report

The whole setup is a bit tricky: In some cases you will build xtensa toolchain code with another GCC than provided from the toolchain. In our case it is unit tests we run on x86 platforms compiled with the local GCC. But even outside this scope the xtensa toolchain will run into the problem when upgrading its GCC.

The stdatomic.h (in ~/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20240305/xtensa-esp-elf/xtensa-esp-elf/include/stdatomic.h) tries to determine the right setup for different compilers:

#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
#define __CLANG_ATOMICS
#elif __GNUC_PREREQ__(4, 7)
#define __GNUC_ATOMICS
#elif defined(__GNUC__)
#define __SYNC_ATOMICS
#else
#error "stdatomic.h does not support your compiler"
#endif

Unfortunately the most recent GCC also replies __has_extension(c_atomic) with true. So we get the define __CLANG_ATOMICS which is obviously for Clang. Consequently the build also fails with:

error: implicit declaration of function ‘__c11_atomic_thread_fence’; did you mean ‘__atomic_thread_fence’? [-Wimplicit-function-declaration]
  143 |         __c11_atomic_thread_fence(__order);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
      |         __atomic_thread_fence

And many other errors if stdatomic.h is somehow included. For now I will workaround that by modifying the xtensa toolchain:

diff stdatomic.h stdatomic-fixed.h 
37c37
< #define       __CLANG_ATOMICS
---
> #define       __GNUC_ATOMICS

But maybe you got a better solution. This issue is also a hint for other users having a similar problem. And to make you aware there is a change necessary when upgrading GCC.

Lapshin commented 1 month ago

Hi @M-Bab !

In some cases you will build xtensa toolchain code with another GCC than provided from the toolchain.

Could you please explain what you want to achieve?

There are my thoughts regarding the ticket:

M-Bab commented 1 month ago

Well there might be other use-cases but ours is unit testing our code. We run the tests on a local x86 platform with Ceedling/Unity/CMock. So far we never had to care about mismatches of the local x86 gcc in the system and the gcc version of the xtensa toolchain.

This is the first time it breaks.

M-Bab commented 1 month ago

What do you think about

#if defined(__clang__) && (__has_extension(c_atomic) || __has_extension(cxx_atomic))
#define __CLANG_ATOMICS
#elif __GNUC_PREREQ__(4, 7)
...
Lapshin commented 1 month ago

@M-Bab , your change looks good!

BTW, did not catch why you need to mix toolchain internals. Anyway, you may be interested in idf.py --preview set-target linux build monitor command. It's still under development but could be useful for unit testing that does not require esp32 hardware..

M-Bab commented 4 weeks ago

BTW, did not catch why you need to mix toolchain internals.

Our unit-tests only run on the host platform - this is an x86 system. And of course it uses the GCC compiler which is installed on the host system. And this can be virtually any modern GCC. We are not mixing toolchains.