Documentation says gcc-arm > 10.2.1 should work, but 12.2.rel1 fails to compile v5.2.0 with:
In file included from /Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/mutex:43,
from ../wiring/inc/spark_wiring_system.h:40,
from ../wiring/inc/spark_wiring.h:49,
from ./inc/application.h:42,
from ./inc/Particle.h:5,
from /Users/lars/Documents/Code/quicly/particle/firmware/main.cpp:28:
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h: In constructor 'std::__condvar::__condvar()':
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h:135:7: error: '__GTHREAD_COND_INIT_FUNCTION' was not declared in this scope
135 | __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h: In destructor 'std::__condvar::~__condvar()':
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h:141:45: error: '__gthread_cond_destroy' was not declared in this scope; did you mean '__gthread_mutex_destroy'?
141 | int __e __attribute__((__unused__)) = __gthread_cond_destroy(&_M_cond);
| ^~~~~~~~~~~~~~~~~~~~~~
| __gthread_mutex_destroy
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h: In member function 'void std::__condvar::wait(std::mutex&)':
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h:155:11: error: '__gthread_cond_wait' was not declared in this scope; did you mean '__gthread_cond_t'?
155 | = __gthread_cond_wait(&_M_cond, __m.native_handle());
| ^~~~~~~~~~~~~~~~~~~
| __gthread_cond_t
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h: In member function 'void std::__condvar::notify_one()':
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h:177:45: error: '__gthread_cond_signal' was not declared in this scope; did you mean '__gthread_cond_t'?
177 | int __e __attribute__((__unused__)) = __gthread_cond_signal(&_M_cond);
| ^~~~~~~~~~~~~~~~~~~~~
| __gthread_cond_t
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h: In member function 'void std::__condvar::notify_all()':
/Applications/ArmGNUToolchain/12.2.rel1/arm-none-eabi/arm-none-eabi/include/c++/12.2.1/bits/std_mutex.h:184:45: error: '__gthread_cond_broadcast' was not declared in this scope; did you mean '__gthread_cond_timedwait'?
184 | int __e __attribute__((__unused__)) = __gthread_cond_broadcast(&_M_cond);
| ^~~~~~~~~~~~~~~~~~~~~~~~
| __gthread_cond_timedwait
It will not. You should use 10.2.1, the version used by the cloud compilers. The instructions really should not say “or later” particularly for major versions, which almost never work without source modifications.
Did you do a make clean in the modules directory, or the equivalent option in Workbench? There could be bits left from a previous compile or when switching between versions, modular/monolithic, or lto/non-lto.
/usr/local/Cellar/gcc-arm-none-eabi-1021/20201103/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /usr/local/Cellar/gcc-arm-none-eabi-1021/20201103/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg_nano.a(lib_a-strerror.o): in function `strerror':
strerror.c:(.text.strerror+0x0): multiple definition of `strerror'; /Users/lars/Documents/Code/quicly/particle/bin//obj/./src/newlib_stubs.o:/Users/lars/.po-util/src/particle/firmware/modules/argon/user-part/../../../modules/shared/nRF52840/inc/user-part/newlib_stubs.inc:92: first defined here
Me neither. And I didn’t get it with earlier versions of Device OS. (The perror is in a library that I am including in my project, so it’s not so easy to eliminate without patching upstream.)
I do think this is a bug in Device OS with the 10.2.1 toolchain, because the libg_nano that comes with gcc does define strerror already:
/usr/local/Cellar/gcc-arm-none-eabi-1021/20201103/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: /usr/local/Cellar/gcc-arm-none-eabi-1021/20201103/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg_nano.a(lib_a-strerror.o): in function `strerror':
strerror.c:(.text.strerror+0x0): multiple definition of `strerror'; /Users/lars/Documents/Code/quicly/particle/target/argon//obj/./src/newlib_stubs.o:/Users/lars/.particle/toolchains/deviceOS/5.2.0/modules/argon/user-part/../../../modules/shared/nRF52840/inc/user-part/newlib_stubs.inc:92: first defined here
After trying to use arm-none-eabi-gcc 12 ourselves, the issue seems to be the following:
The updated newlib that comes with version 12 uses new symbols for gthread, for example
__GTHREAD_COND_INIT_FUNCTION instead of __GTHREAD_MUTEX_INIT_FUNCTION
Particle's hal defines the abstractions in this file: device-os/hal/src/stm32/bits/gthr-default.h
These are not fully compatible with the latest newlib.
It seems that support for the P1 has stopped, so we're out of luck trying to offer long term support to our customers, while trying to keep our build system up to date for other platforms.
Another issue is the olddated nanopb lib on P1. It was recently updated for gen3, but not backported to P1.
LTS only means that it works if you keep using outdated dependencies and compilers.