zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.59k stars 6.48k forks source link

C++ 11 Support #4028

Closed zephyrbot closed 4 years ago

zephyrbot commented 7 years ago

Reported by Soheil Qanbari:

Hi,

Based on the C++ Support for Applications page:

http://zephyr-docs.s3-website-us-east-1.amazonaws.com/online/dev/kernel/other/cxx_support.html

Is there any plan on when to support the following c++ functionalities?

Dynamic object management with the new and delete operators
Vectors
RTTI
Exceptions
Static global object destruction

This will open a great space to deploy c++ applications on Zephyr too. I appreciate any input.

Thank you.

(Imported from Jira ZEP-2599)

zephyrbot commented 7 years ago

by Andy Ross:

RTTI and exceptions would be possible with (mostly) just a few compiler flags. Note that both have siginificant code size implications which make them sorta poor choices for an RTOS environment. And like all mixed C/C++ environments, exceptions will be tricky to use in Zephyr: you have to throw them and catch them from within "pure" C++ code. If there is a C function on the stack between your throw and catch (e.g. a driver or network stack callback, etc...) it won't work.

I'd expect new/delete to work normally right now, as-is, as long as you are linking against newlib which includes a (mostly) working malloc. We could wire up k_malloc() for that purpose too, though again most of our targets have a very constrained heap. It hasn't been a priority, but I don't think much would be required to validate this usage.

Not sure what you want a static destructor for. You want to hook the destructors to run at a "system shutdown" moment? We don't have that, though I guess we could add it.

zephyrbot commented 7 years ago

by Soheil Qanbari:

Thank you, Andy Ross , really. Your reply means a lot to us. :)

We have a little engine and would love to build it for ZEP, as we believe it is the future generation of RTOSs.

I will come back to you shortly with the short list of libraries that we need and would be very thankful for your comment on them.

My sincere thanks again.

zephyrbot commented 7 years ago

by Soheil Qanbari:

Hi Andy Ross ,

I hope you are doing well. We need the libs for threads, iostream, vector, map, set,... Here are the includes we need to build our engine on the Microcontroller using ZEP.

#include <iostream>
#include <string>
#include <exception>
#include <functional>
#include <vector>
#include <map>
#include <mutex>
#include <tuple>
#include <type_traits>
#include <sstream>
#include <iomanip>
#include <functional>
#include <cstring>
#include <algorithm>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <fstream>
#include <dlfcn.h>
#include <assert.h>
#include <cstdint>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <set>
#include <iterator>
#include <memory>
#include <limits>
#include <stack>
#include <cctype>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/stat.h>

Is there any wiki, list, or documentation on the detail c++ support?

I appreciate your input really and thank you in advance...

zephyrbot commented 7 years ago

by Andy Ross:

There's absolutely no way that all of that is going to be supported. In particular the POSIX-based filesystem stuff doesn't exist in Zephyr. We aren't a unix.

Things that work directly on memory and are header-only libraries (e.g. STL & the rest of the containers and algorithms stuff) should be OK when linked with newlib (which provides the heap). Things that work with the underlying OS are going to need significant porting to work with Zephyr.

Tenderson commented 6 years ago

Thank you, @andyross ,

I just tried this simple C++ program with the newlib to check the new/delete operators, however I get a strange result. Can you please take a quick look on the issue?

in prj.conf:

CONFIG_CPLUSPLUS=y
CONFIG_NEWLIB_LIBC=y

in main.cpp:

#include <zephyr.h>
#include <misc/printk.h>

int main()
{
  int* foo = new int[5];

  for (int n = 0; n < 5; n++){    
    foo[n]=n;
    printk("foo[%d] = %d\n",n, foo[n]);
  }
  delete[] foo;
  return 0;
}

output:

[QEMU] CPU: cortex-m3 foo[0] = 536872584 foo[1] = 3989 foo[2] = 4073 foo[3] = 3641 foo[4] = 3641

andrewboie commented 6 years ago

new and delete aren't implemented. the stubs are at the bottom of include/kernel.h. you could perhaps hook them up to newlib's malloc() and free().

Tenderson commented 6 years ago

Thank you, @andrewboie

I commented out the stubs at the bottom of include/kernel.h, and tried to cross compile the code above with the GCC ARM Embedded

Here is the error I receive about the undefined new/delete operators. However, I was expecting the build of the application using the new/delete operators available in the GCC ARM Embedded compiler. But it still looks for the overloaded operators in the kernel.h. Could you please advice on this?

Is this the right expectation?

Shall I config anything else for the cross compile? I just followed the instructions here.

I truly appreciate your input.

ubuntu@ubuntu-xenial: ~ /ZEPHYR/samples/hello_world_cpp $ 
make CROSS_COMPILE=~/ZEPHYR/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- BOARD=qemu_cortex_m3
make[1]: Entering directory '/home/ubuntu/ZEPHYR'
make[2]: Entering directory '/home/ubuntu/ZEPHYR/samples/hello_world_cpp/outdir/qemu_cortex_m3'
  CHK     include/generated/generated_dts_board.conf
  Using /home/ubuntu/ZEPHYR as source for kernel
  GEN     ./Makefile
  CHK     include/generated/version.h
  CHK     include/generated/generated_dts_board.h
  CHK     misc/generated/configs.c
  CHK     include/generated/offsets.h
src/built-in.o: In function `main':
/home/ubuntu/ZEPHYR/samples/hello_world_cpp/src/main.cpp:11: undefined reference to `operator new[](unsigned int)'
/home/ubuntu/ZEPHYR/samples/hello_world_cpp/src/main.cpp:20: undefined reference to `operator delete[](void*)'
collect2: error: ld returned 1 exit status
/home/ubuntu/ZEPHYR/Makefile:878: recipe for target 'zephyr_prebuilt.elf' failed
make[2]: *** [zephyr_prebuilt.elf] Error 1
make[2]: Leaving directory '/home/ubuntu/ZEPHYR/samples/hello_world_cpp/outdir/qemu_cortex_m3'
Makefile:178: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory '/home/ubuntu/ZEPHYR'
/home/ubuntu/ZEPHYR/Makefile.inc:82: recipe for target 'all' failed
make: *** [all] Error 2
Tenderson commented 6 years ago

@andrewboie @andrewboie Any thoughts on this issue is highly appreciated.

mrusme commented 5 years ago

It would be very helpful if there was a little bit more than this to understand better how to use C++ with Zephyr and which C++ standard is actually supported. Maybe I'm overlooking something here.

Could anyone provide further details about which C++ standard (98, 03, 11, ...?) is currently supported and maybe give a tiny Hello World example on how C and C++ can be mixed? Thanks in advance!

pabigot commented 5 years ago

@mrusme The application in tests/application_development/libcxx is the most complete; right now there's no link in the documentation ~but I'll fix that~ because it's a test, not a sample. That example targets C++17. 03 is missing for unknown reasons, but 98, 11, 14, 17, and 2A can all be specified with (e.g.) CONFIG_STD_CPP17.

There are still significant limitations including use of dynamic object creation, virtual functions, and exceptions. Any or all of them may work in some circumstances, configurations, and tool chains.

pabigot commented 4 years ago

In #18554 this issue was associated with lack of support for compiling with exceptions, which has been resolved by #19002. At this time I'm going to say that this issue is complete; there are gaps, but we need more targeted issues that clearly define the scope of work.