Creating a new project with Eclipse for a microcontroller these days is fairly easy, and I have the choice if I want to start the project with C or C++:
Still the embedded microcontroller world is dominated by C and not C++. So while it is easy to start with a C++ project, most vendor provided example or tutorial project are C projects. So how can I transform such project to C++?
To have C++ support in an Eclipse CDT project, I need basically two things:
- The project needs the C++ ‘nature’: with this I get the C++ compiler/build options
- The startup code needs to call the global C++ constructors
- Change the library settings
With this, I can add my C++ files to a former C project. The steps described here should be applicable to any Eclipse CDT project. Things might be different in details depending on your Eclipse distribution or SDK. I’m showing here screenshots using the NXP MCUXpresso IDE V11.1.1 using an SDK project provided as C language project (frdmk22f_led_blinky).
If a project has been created as C project, then usually it only shows the options for the C compiler:
To enable the project for C++, the following nature has to be added to the .project file.
One way is to use the File > New menu and then select ‘Convert to a C/C++ Project (Adds C/C++ Nature):
Another way to to this is using a text editor, either inside or outside Eclipse:
💡 Be careful with using Eclipse built-in Editor. Close the project and re-open it afterwards.
Alternatively the Eclipse built-in XML editor can be used to add the nature:
With latest CDT it is possible to add/remove a nature in the project properties too (although it is confusing as the C++ (CC) nature is shown as ‘C Nature’) (thanks to Jld00 for his comment!):
With this the settings include the C++ compiler options (close and re-open the project if the change has been made inside Eclipse):
With this I can set compiler options for the C++ files in the project.
C++ Startup Code
Locate the C startup code in the project:
The easiest approach is to rename it to a C++ file with .cpp extension:
With this the startup code gets compiled in C++ mode. This assumes that the startup code is prepared in written in a way that it actually can be compiled in C++ mode and that it uses the appropriate ‘__cplusplus’ macros). The important thing is that in C+ mode it calls the global constructors. With the NewLib/Newlib-Nano libraries this is a call to the __libc_init_array() function before calling main():
The __libc_init_array() basically is a list of functions prepared by the linker with global initializers to initialize the library and call all the global constructors.
💡 to verify that the constructors get called, have a global object defined and set a breakpoint in the constructor code.
With this the proper library initialization is done and constructors for global objects are called.
The last thing is to make sure that the correct library is used. Reduced libraries like the ‘RedLib’ in MCUXpresso does not support C++ and cannot be used. NewLib-nano is optimized for size and does support C++ applications, but does not include exception handling by default (see links at the end of the article).
Check the library used: newlib-nano is fine if not using exceptions, otherwise switch to newlib (but be prepared for a code size increase):
Another way to select/switch the library is in the linker settings:
With this the library can be used with C++.
It requires a few steps to turn a normal C project into a C++ enabled one: make sure the C++ nature is selected, the startup code is calling the global constructors and a C++ capable library is used.
Happy C++ing 🙂