Skip to main content
TLeaf
Associate
May 27, 2019
Question

How to configure STM32CubeIDE to support C++ development?

  • May 27, 2019
  • 26 replies
  • 40319 views

1. How to configure the IDE to use g++ compiler to compile all the files includes "*.c" files in the project?

Current it compiles the .c files by using gcc and .cpp by using g++ ...

2. If I rename main.c to main.cpp, the cube code generator will create a new main.c file instead of using main.cpp. Any sulotions for this?

Becasue main.c is .c file, so the IDE use gcc to compile this file, and this caused that I can't use any objects in it. But if I changed the main.c to main.cpp, the cube can't generate code into it...:face_screaming_in_fear:

26 replies

Markus GIRDLAND
ST Employee
May 27, 2019

Have you converted the project?

By right-clicking the project and selecting "New -> Convert to a C/C++ Project (Adds C/C++ Nature)" you should be able to convert. And cube is supposed to still generate code for the project afterwards.

If you're starting a new project you can also select it during project creation.

TLeaf
TLeafAuthor
Associate
May 28, 2019

Thank you for providing the solution, but it still haven't solved my problem.

Please see my clarification below

Fahad Mirza
Associate III
August 14, 2019

I know it is an old thread. But I had the same issue. I initially started with a 'C' project and then wanted to turn it into 'C++' project. This is how it worked for me:

1) Right Click on the project file and select 'Convert to C++' (Note: The image shows convert to C because I already changed it to C++)

0690X00000A9bihQAB.jpg

2) Then I changed the main.c to main.cpp by right click on the main.c and click 'Rename'. This is important. DON'T change it manually. If you change using 'Rename' there shouldn't be any problem.

At least that worked for me.

SpinKernel
Associate III
August 21, 2019

Thanks, that worked for me (I didn't rename the main.c file, which was my problem).

I still have issues with .h files not compiling correctly, i assume I have to name them .hpp? or .hh? I'll play with it now that i know.

Fahad Mirza
Associate III
August 21, 2019

Are you talking about including '*.h' that belongs to a '*.c' file? If so, you need ---- extern "C" ---- like this:

#ifndef DUMMY_H_
#define DUMMY_H_
 
#ifdef __cplusplus
 extern "C" {
#endif
 
 // Function declarations here
 
#ifdef __cplusplus
}
#endif
#endif /* DUMMY_H_ */

 If not, post your errors.

Harvey White
Senior III
August 22, 2019

Just got finished with this: What I've managed is.....

C++ can call C, but I've not had any success the other way around.

so the following:

1) I've rewritten all of my code into C++ (NOT main.c)

2) any C++ routine calls a C routine, but there are no C routines to call a C++ routine

3) I'm using FreeRTOS, which is written in C, but has the C++ nature included *if* the compiler is working in a C++ environment

so do the following:

1) create a basic project using main.c

2) create your main program application as a C++ loop, calling what you will

3) since this is FreeRTOS, you want a setup, which creates a task, then a task, that task is your main application loop

4) all these are in C++

5) I have a bridge routine in C++ that is called, that calls the create task for the main application loop, that's all it does

6) before the RTOS loop in main.c, call the bridge program to start your program. That application loop takes over the functions of the loop in the main program

7) rename (from the IDE) main.c to main.cpp

8) program should run

9) to make any changes to the environment through cubeMX, rename main.cpp back to main.c

10) make changes as needed

11) rename main.c to main.cpp (if you don't, you get errors. Then rebuild and reindex the project)

12) any time you need to rework the cubeMX settings, you must rename main.cpp to main.c first, then name it back again.

All that is needed for CubeMX to do is to generate code and recognize that a main.cpp file is valid. That ought to run for this scenario.

Since CubeMX doesn't do this yet, you need to.

When I write C++ code, I do change the extensions to .cpp and .hpp

One thing I found is that it was very convenient to keep the c and cpp code in different directories

limit the c compiler to the C directories, and limit the C++ compiler to the C++ directories.

I've gotten errors when the C compiler mistakenly tries to understand a C++ file and cannot recognize C++ keywords.

rbarris
Associate II
September 4, 2020

I'm running into this same type of problem here in September of 2020...

Create a working project through the wizard, even checked the "C++" language box, all the ST Cube / HAL code is still in C but that's fine, I can write a couple glue functions and keep the C++ stuff in my own sources.

I add a single .cpp file to the project, I put it in CM7/Core/Src ("buzz.cpp").

I added a header file ("buzz_glue.h") and the main.c is able to include it and see the prototypes for the C glue functions.

But my .cpp file never gets compiled, and the link fails.

I know it's not getting compiled because I put some garbage and an "#error 1" in the .cpp and it's ignored.

As an aside, the "Convert to C++" menu item that keeps coming up in these threads, is gone in 1.4.2, or I don't know which thing I actually should click on.

As an experiment, I went back and (through the IDE) created a new source file in Src, "dummy.c", and put an #error 1 in it, dummy.c does get an attempt to compile which fails.

So the symptom that I have is that if I add a .cpp file to this project, it is ignored. Which leads me to believe that I don't really have a C++ project. I don't know how to create one, and I don't see the option to convert C to C++ afterward.

So

a) even though I asked for a C++ project in the setup dialog, it's not really acting like one

b) the C side seems to see the header I added

c) the CPP file I added is being ignored

d) the "convert to C++" menu option is nowhere to be found

[UPDATE - I found the "Convert to C++" menu item, I had the wrong tab open, you only get it when you have "project explorer" open on the left sidebar and not "C/C++ Projects" - will see if that unblocks me. ]

0693W000003QqGPQA0.png0693W000003QqGFQA0.png0693W000003QqGAQA0.png

TMaia.1
Associate
September 25, 2020

Just to be sure. There is no way that MX can generate a main.cpp file, right?

Harvey White
Senior III
September 25, 2020

Correct, it cannot. None of the auxiliary programs are in C++, all in C.

Generate a routine (I use the name of CPP_LINK.CPP

/*
 * CPP_LINK.cpp
 *
 * Created on: Jul 12, 2019
 * Author: madyn
 */
 
#include "configuration.h"
#include "CPP_LINK.hpp"
 
//#ifdef PROJECT_MODULAR_POWER_LK432
//	#include "Power_CPU_APP.hpp"
//#endif
//
//#if (defined PROJECT_MODULAR_CPU_F767)
//	#include "TRICORDER_MK30_APP.hpp"
//#endif
//
//#if (defined PROJECT_TRICORDER_MK30_5)
//	#include "TRICORDER_MK30_5_APP.hpp"
//#endif
//
//
//#if (defined PROJECT_TRICORDER_MK40)
//	#include "TRICORDER_MK40_APP.hpp"
//#endif
//
//
//#if (defined PROJECT_TRICORDER_MK30_4)
//	#include "TRICORDER_MK30_4_APP.hpp"
//#endif
 
	#include "APPLICATION.hpp"
 
#ifdef __cplusplus
	extern "C"
	{
#endif
 
	void cpp_link (void)
		{
			APPLICATION_init();
		}
 
#ifdef __cplusplus
	}
#endif

and then generate CPP_LINK.hpp

/*
 * CPP_LINK.hpp
 *
 * Created on: Jul 12, 2019
 * Author: madyn
 */
 
#ifndef CPP_LINK_HPP_
#define CPP_LINK_HPP_
 
	#ifdef __cplusplus
		extern "C"
		{
	#endif
 
		void cpp_link (void);
 
	#ifdef __cplusplus
		}
	#endif
#endif /* CPP_LINK_HPP_ */

From your main routine, call

void StartDefaultTask(void const * argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
	 cpp_link();
	 // NEVER GETS HERE, cpp_link goes to application init and then loop
 for(;;)
 {
 osDelay(10000);
 }
 /* USER CODE END 5 */ 
}
 

Everything else in the program that I write is C++. C++ calls C without a problem, C has a problem calling C++.

C++ nature has been added to the project.

The way this is structured, the main.c program can be generated and regenerated as needed. The bridge (CPP_LINK.cpp) never changes as long as you make your program "application.cpp"

Application init simply sets up the main task and goes from there.

Harvey White
Senior III
February 11, 2024

I should point out an error that the code somewhat obscured.

CPP_LINK sets things up and then returns, so the main user loop does run.  The delay of 10000 clock ticks says that it will run, delay for 10 seconds, then run again.  If you wanted to put something there, it would work.  Structurally, however, I generally don't.

 

Luczia
Associate II
October 14, 2020

Hi,

I've noticed a problem that is even deeper/weirder:

When creating a project from scratch, it works for me :

  • Create a brand new project (File > New > STM32 Project > Board Selector > F401RE and then Check C++ in the targeted language field)
  • In the CubeIDE navigation tree, right click on main.c and rename to main.cpp
  • Try to create a class in main.cpp => Compilation works :ok_hand:

But when creating a project from an example(File > New > STM32 Project > Board Selector) or opening an existing project, the manipulation (right click > Convert to C++ and then rename the extension of main.c to main.cpp) dosen't change anything. ie : I can see on the compliation log that main.c (even though I renamed it "main.cpp" through Cube IDE) is compiled with gcc and not g++.

Also, very weird : If I double check in the windows explorer, the file is still named main.c. It seems that for some project architectures, CubeIDE and the compiler doesn't take into account the renaming of the file.

Below, a screnshot (top project (My-Project) does compile with g++ and bottom project (UART_printf) doesn't compile with g++) ¯\_(ツ)_/¯

0693W000004JneJQAS.png 

Any tips or thoughts on that ?

main.cpp has to be in the Src folder and not anywhere else, maybe ?

Has anyone ever succeded in converting an ST32 example to compile in C++ ?

Harvey White
Senior III
October 14, 2020

Any program source (.c or .cpp) has to be in the SRC directory, and any .h or .hpp file has to be in the inc directory. Having said that, there are some tricks you can pull:

1) I do large projects with common routines acting as libraries

2) There is an application file and a configuration file (as well as screen files) generated by a graphics/project configuration program that handles linking buttons and screens, as well as generating conditional installs for optionally included hardware.

The trick, though, when having common sources to a number of projects is to use virtual folders. If (and when) you add/include a file to the project, the default behavior is to take a copy of that file and put it in the project's .src or .inc directory. Making (and including these) as virtual folders links everything back to a single copy.

Cube (anything) creates only a C file, not C++. Make any changes in configuration, and you add the new file main.c (and main.h). If you already have these, you overwrite the existing copies. If you've renamed your files main.cpp and main.hpp, then you don't change them, you simply overwrite or generate the .c or .h files. The problem is also that I'm using FreeRTOS, which is not (and may never be) C++.

Better to tweak the main file to call your C++ file and leave it at that.

I have the cube generated .c files calling a single statically named .cpp bridge file, which can call the application .cpp file. Any operating system calls are to C routines, and any low level calls to HAL routines are C++ to C, which works.

Since (in my case) the configuration.h file is project unique, it goes into the project's inc directory, as the application.cpp goes into the SRC directory. This also means that each project has an application.cpp and configuration.cpp, and they had better be kept separate.

Since I don't use their examples, other than perhaps reference, I've never really tried converting an example to C++. If all you're doing is examples, then as you create the project, I'd think the INC and SRC directories will load up. Each project needs a separate directory, of course.

So in short. Yes, everything seems to want to be (mostly) in the .src and .inc directories, either direct copies or virtual folders.

If you get to larger projects, all customized from a set of main routines, some of the above may be useful.

VBurs
Associate III
November 12, 2020

I have the same issue, i can make a cpp project, have the cubemx generate all the files in C, then rename the main.c into main.cpp but when i regenerate with cubemx, it generates a new main.c

To make it work i have to change the main.cpp into main.c, do the cubemx generation, then rename the modified main.c into main.cpp

It is quite anoying to be frank and it feels like this can be easily patched in the cubemx source code.

Harvey White
Senior III
November 12, 2020

If you modify the main.c without renaming it, putting your code in the user defined sections, then you can call a C++ routine from C. This saves the annoyance of having to rename the main.c. I did make the suggestion that if cubemx does find a main.cpp then it ought to just use it instead of a main.c file. Haven't seen that happen at all, though.

I've gone though a lot of changes, project wise, to the main.c and main.h file, and haven't had a problem calling my C++ application loop from the main.c program.

Details are earlier in the thread, involving adding some conditionals for C++.

VBurs
Associate III
November 12, 2020

For reference for all new people looking to do convert their projects into cpp: https://shawnhymel.com/1941/how-to-use-c-with-stm32cubeide/