nuttx
nuttx copied to clipboard
libxx "C++ Example using CMake" guide "No thread API" error
I am new to NuttX and I have been trying to use the "C++ Example using CMake" guide available in the official documentation. No changes whatsoever to code. That is:
cd nuttx
./tools/configure.sh stm32f4discovery:testlibcxx
Set RTOS Features -> Tasks and Scheduling -> Application entry point to ‘hellocpp_main’
make export
And in the hellocpp/ main folder:
mkdir build
cd build
cmake ..
make
I have tested Nuttx 10.0.1, 10.1.0 and 10.2.0. The first one does not export. The other two appear to be OK while doing cmake ..
(edited just folder names due to NDAs):
$ cmake ..
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++
-- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/hellocpp/build
However, make
ends in the same error for both :
$ make
Scanning dependencies of target hellocpp
[ 33%] Building CXX object src/CMakeFiles/hellocpp.dir/HelloWorld.cpp.obj
In file included from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/cstdio:98,
from /path/to/hellocpp/src/HelloWorld.cpp:1:
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__config:1142:6: error: #error "No thread API"
1142 | # error "No thread API"
| ^~~~~
In file included from /path/to/hellocpp/nuttx-export-10.1.0/include/nuttx/sched.h:33,
from /path/to/hellocpp/nuttx-export-10.1.0/include/sched.h:36,
from /path/to/hellocpp/nuttx-export-10.1.0/include/stdio.h:32,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/cstdio:99,
from /path/to/hellocpp/src/HelloWorld.cpp:1:
/path/to/hellocpp/nuttx-export-10.1.0/include/signal.h:416:42: warning: 'int sigaction(int, const sigaction*, sigaction*)' hides constructor for 'struct sigaction' [-Wshadow]
416 | FAR struct sigaction *oact);
| ^
In file included from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/cstddef:44,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/initializer_list:46,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/algorithm:639,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__string:57,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/string_view:175,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/string:506,
from /path/to/hellocpp/src/HelloWorld.cpp:2:
/usr/lib/gcc/arm-none-eabi/9.2.1/include/stddef.h:426:3: error: conflicting declaration 'typedef struct max_align_t max_align_t'
426 | } max_align_t;
| ^~~~~~~~~~~
In file included from /path/to/hellocpp/nuttx-export-10.1.0/include/string.h:30,
from /path/to/hellocpp/nuttx-export-10.1.0/include/strings.h:30,
from /path/to/hellocpp/nuttx-export-10.1.0/include/sched.h:33,
from /path/to/hellocpp/nuttx-export-10.1.0/include/stdio.h:32,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/cstdio:99,
from /path/to/hellocpp/src/HelloWorld.cpp:1:
/path/to/hellocpp/nuttx-export-10.1.0/include/stddef.h:105:3: note: previous declaration as 'typedef struct max_align_t max_align_t'
105 | } max_align_t;
| ^~~~~~~~~~~
In file included from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/atomic:571,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/memory:681,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/algorithm:643,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__string:57,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/string_view:175,
from /path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/string:506,
from /path/to/hellocpp/src/HelloWorld.cpp:2:
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__threading_support:270:55: error: expected ')' before '*' token
270 | void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
| ~ ^
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__threading_support:270:55: error: expected ')' before '*' token
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__threading_support:269:24: note: to match this '('
269 | int __libcpp_tls_create(__libcpp_tls_key* __key,
| ^
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__threading_support:270:55: error: expected initializer before '*' token
270 | void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
| ^
make[2]: *** [src/CMakeFiles/hellocpp.dir/build.make:63: src/CMakeFiles/hellocpp.dir/HelloWorld.cpp.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:94: src/CMakeFiles/hellocpp.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
I have found this link as a person that had a similar problem, but I could not pinpoint in the discussion what should I do to make it work. I also understood that #1592 should have fixed the issue. What am I missing?
Small update on this error:
/path/to/hellocpp/nuttx-export-10.1.0/include/libcxx/__config:1142:6: error: #error "No thread API"
1142 | # error "No thread API"
| ^~~~~
It is caused because there is no definition of __NuttX__
whatsoever in any of the files created by make export
. From the little I could find, it appears that it has been moved from the individual Make.defs to tools/Config.mk by #2192 . Inserting it back on the Make.defs made no diference.
For the purpostes of getting rid of it, I have hardcoded the definition in the HelloWord.h of said guide. But I am quite sure this is not how it is supposed to be done. So, if anyone has any input, specially considering updating the guide, it'd be highly appreciated.
Now to the next error:
In file included from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/cstddef:44,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/initializer_list:46,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/algorithm:649,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/__string:57,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/string_view:179,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/string:511,
from /path/to/hellocpp/src/HelloWorld.cpp:4:
/usr/lib/gcc/arm-none-eabi/9.2.1/include/stddef.h:426:3: error: conflicting declaration 'typedef struct max_align_t max_align_t'
426 | } max_align_t;
| ^~~~~~~~~~~
In file included from /path/to/hellocpp/nuttx-export-10.2.0/include/string.h:30,
from /path/to/hellocpp/nuttx-export-10.2.0/include/strings.h:30,
from /path/to/hellocpp/nuttx-export-10.2.0/include/sched.h:33,
from /path/to/hellocpp/nuttx-export-10.2.0/include/nuttx/sched.h:33,
from /path/to/hellocpp/nuttx-export-10.2.0/include/stdio.h:35,
from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/cstdio:99,
from /path/to/hellocpp/src/HelloWorld.cpp:3:
/path/to/hellocpp/nuttx-export-10.2.0/include/stddef.h:83:3: note: previous declaration as 'typedef struct max_align_t max_align_t'
83 | } max_align_t;
| ^~~~~~~~~~~
The error: conflicting declaration 'typedef struct max_align_t max_align_t'
appears to come from /include/libxx/cstddef lines 43-45:
// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
#include_next <stddef.h>
#include <__nullptr>
The #include_next
causes the compiler to use its own stddef.h instead of NuttX's while /include/strings.h. Changing line 44 to #include <stddef.h>
fixes this specific error. Still, as this comes from an external lib, I once again do not believe that this is the most correct approach. Any advice in how to update the guide is helpful.
Onto the next....
make
Scanning dependencies of target hellocpp
[ 33%] Building CXX object src/CMakeFiles/hellocpp.dir/HelloWorld.cpp.obj
[ 66%] Building CXX object src/CMakeFiles/hellocpp.dir/main.cpp.obj
[100%] Linking CXX executable hellocpp
/usr/bin/arm-none-eabi-ld: cannot find -lsupc++
make[2]: *** [src/CMakeFiles/hellocpp.dir/build.make:99: src/hellocpp] Error 1
make[1]: *** [CMakeFiles/Makefile2:94: src/CMakeFiles/hellocpp.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
I've made some changes based at what you mentioned and the discussion at the link.
First I added the #define NuttX at the CMakeLists.txt here:
set(AC_DEFINES "${AC_DEFINES} -D__NuttX__ -DCONFIG_WCHAR_BUILTIN")
This solves the question about error: #error "No thread API".
After this, I had an error about the lsupc++ lib. Looking at NuttX repository for this lib, I found out there is a config LIBSUPCXX to enable this lib.
So I enabled this config using:
make menuconfig
With this config enabled I ran:
./tools/configure.sh stm32f4discovery:testlibcxx
make export
Following the steps mentioned at the example guide, new error appeared:
arm-none-eabi-objcopy: '/nuttxspace/hellocpp/build/hellocpp.elf': No such file
I don't know why hellocpp.elf is generated inside src folder, but after copying from src to build folder I have the following result:
[ 33%] Linking CXX executable hellocpp
[100%] Built target hellocpp
The final result at build folder:
/nuttxspace/hellocpp/build$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake hellocpp.bin hellocpp.elf Makefile src
Thanks @flavioipiranga for your help! About the .elf file, changing line 16 from /src/CMaleLists.txt saves you from having to copy the file. The updated line that fixed it for me was:
COMMAND ${CMAKE_OBJCOPY} ARGS -S -O binary ${CMAKE_BINARY_DIR}/src/${EXE_NAME}.elf ${CMAKE_BINARY_DIR}/${EXE_NAME}.bin
And, likewise, here changing from "LLVM low level C++ Library" to "GNU low level libsupc++" does compile. I personally wanted to use LLVM, but that is my issue, not an issue with the guide.
Now to the next error:
In file included from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/cstddef:44, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/initializer_list:46, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/algorithm:649, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/__string:57, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/string_view:179, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/string:511, from /path/to/hellocpp/src/HelloWorld.cpp:4: /usr/lib/gcc/arm-none-eabi/9.2.1/include/stddef.h:426:3: error: conflicting declaration 'typedef struct max_align_t max_align_t' 426 | } max_align_t; | ^~~~~~~~~~~ In file included from /path/to/hellocpp/nuttx-export-10.2.0/include/string.h:30, from /path/to/hellocpp/nuttx-export-10.2.0/include/strings.h:30, from /path/to/hellocpp/nuttx-export-10.2.0/include/sched.h:33, from /path/to/hellocpp/nuttx-export-10.2.0/include/nuttx/sched.h:33, from /path/to/hellocpp/nuttx-export-10.2.0/include/stdio.h:35, from /path/to/hellocpp/nuttx-export-10.2.0/include/libcxx/cstdio:99, from /path/to/hellocpp/src/HelloWorld.cpp:3: /path/to/hellocpp/nuttx-export-10.2.0/include/stddef.h:83:3: note: previous declaration as 'typedef struct max_align_t max_align_t' 83 | } max_align_t; | ^~~~~~~~~~~
The
error: conflicting declaration 'typedef struct max_align_t max_align_t'
appears to come from /include/libxx/cstddef lines 43-45:// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t. #include_next <stddef.h> #include <__nullptr>
The
#include_next
causes the compiler to use its own stddef.h instead of NuttX's while /include/strings.h. Changing line 44 to#include <stddef.h>
fixes this specific error. Still, as this comes from an external lib, I once again do not believe that this is the most correct approach. Any advice in how to update the guide is helpful.
If we are talking about an example. In the "hellocpp/CMakeLists.txt" try to change the order of paths for including from:
include_directories(
src
${NUTTX_PATH}/include
${NUTTX_PATH}/include/libcxx
${NUTTX_PATH}/arch/chip
)
to
include_directories(
src
${NUTTX_PATH}/include/libcxx
${NUTTX_PATH}/include
${NUTTX_PATH}/arch/chip
)
It should work like this.
kind of off-topic. But how do you guys flash hellocpp.bin
to your board using openocd
?
kind of off-topic. But how do you guys flash
hellocpp.bin
to your board usingopenocd
?
pyocd might be better
kind of off-topic. But how do you guys flash
hellocpp.bin
to your board usingopenocd
?pyocd might be better
how do you do it?
i have fixed the build https://github.com/huanglilong/stm32h7_fmu
I think it might be interesting for you guys as well. Check out the following PR #10398. It automatically generates a cmake toolchainfile that you can use to build cpp applications. It would be great if we have different projects/people that test it that way we can modify it to make it as generic as possible.