2019-05-27 2:00 AM
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:
2021-11-03 11:39 PM
I've just been renaming main.cpp back to main.c any time I want to change the ioc. I rename back to main.c, let it generate it's code, then rename back to .cpp so things compile properly.
It's a bit of a pain, but it's what works for me.
2021-11-04 8:24 AM
I have forgotten to rename the .cpp to .c every now and then. Using the idea of a linking program lets you keep the .c file, and no renaming is needed. I opted for a permanent solution rather than "remember to do this each time."
2022-08-14 12:25 PM
Il est possible de renommer le fichier main.c en main.cpp et de convertir ensuite le projet en C++.
Ensuite, il faut prendre le soin d'ajouter extern "C" juste après l'insertion des directives de préprocesseur #include afin de prendre en compte le langage C dans le fichier main.cpp
Le compilateur gcc compilera les fichiers d'extension .c et g++ compilera séparément les fichiers d'extension .cpp
J'espère que ce post résoudra le problème de nombre de programmeurs.
Cordiales salutations,
Dom
2022-08-14 12:35 PM
2022-08-16 7:48 AM
Sorry for this necromancy, but this is simple problem I think.
A.h must be understandable for both C and C++ compilers.
In example below, Serial.h is C++ header with some classes and so on. A.h is included in main.c and both setup() and loop() functions are called in main.c.
A.h:
#ifndef INC_A_H_
#define INC_A_H_
// C INCLUDES
#include "main.h"
#ifdef __cplusplus
extern "C" {
// CPP INCLUDES
#include "Serial.h"
#endif
// DECLARATIONS
void setup();
void loop();
#ifdef __cplusplus
}
#endif
#endif /* INC_A_H_ */
A.cpp:
#include "A.h"
class CustomType {
};
void setup() {
}
void loop() {
}
2024-02-10 9:12 PM
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.
2025-05-10 9:48 PM
STMCubeIDE cannot handle directly C++ projects in 2025, so they will always must start with the main.c file as the entry point, no matter whether you've created a C++ project or you've converted a C project into a C++ one, as you were said before.
What I always do (all my projects are C++ based) is to use the main.c file as trampolin to a MainApp.cpp file (and function) so that all magic starts there.
In the header of the main.c file write:
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "MainApp.hpp"
/* USER CODE END Includes */
After the initialization code you call the MainApp() function (Line 11):
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
MX_USART2_UART_Init();
MX_CRC_Init();
MX_SPI1_Init();
MX_TIM6_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
MainApp();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
You will need a MainApp.hpp file with this code:
#ifndef INC_MAINAPP_HPP_
#define INC_MAINAPP_HPP_
#ifdef __cplusplus
extern "C" {
#endif
void MainApp();
#ifdef __cplusplus
}
#endif
#endif /* INC_MAINAPP_HPP_ */
Finally the MainApp.cpp file with your C++ code:
// System headers for the hardware you're going to use:
#include "main.h"
#include "crc.h"
#include "rtc.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
#include "tim.h"
// Trampolin file:
#include "MainApp.hpp"
void MainApp()
{
while( 1 )
{
// whatever you want in here...
}
}
IMPORTANT: The MainApp.hpp file is located inside the Inc/ folder, whilst MainApp.cpp is located into the Src/ folder.
Hope it helps in 2025.
2025-05-11 7:40 AM
I see how this works. (the XMEGA code generated by the old AVR studio used a trampoline to be able to deal with extended memory).
How do you deal with frequent changes to the project in CubeMXIDE? It seems that you are copying the autogenerated setups and calls into your C++ routine. CubeMX always generates the setups based on it's interactive settings, but (of course) only as main.c. I picked a separate trampoline file that the main loop calls (always using FreeRTOS since the programs I write are complex enough to need it). That way, the changes due to CubeMX are always reflected.
As an evolutionary note:
the CPP_LINK file calls my drivers for SPI, Serial, and I2C based on a board.h configuration file. My drivers are in C++, calling the hal level drivers. Mine wrap the hal drivers in semaphores, and allow blocking, interrupt, queue, and DMA access. So setting up low level drivers happens here.
The CPP_LINK also sets up the main task, The main task sets up system level drivers, which are intended to be the main interface to all hardware and subsystems. System interfaces don't care where the hardware is as long as there's a communications link to the other (or same) processor.
Of course, this would be a lot easier if CubeMXIDE would simply recognize a main.cpp and main.h (or .hpp) file and modify it. If no such file exists, then simply generate the main.c file as normal. Keeps you from having to rename the main.c to main.cpp.
2025-05-12 10:30 PM
How do you deal with frequent changes to the project in CubeMXIDE? It seems that you are copying the autogenerated setups and calls into your C++ routine. CubeMX always generates the setups based on it's interactive settings, but (of course) only as main.c. I picked a separate trampoline file that the main loop calls (always using FreeRTOS since the programs I write are complex enough to need it). That way, the changes due to CubeMX are always reflected.
I'm not pretty sure if I understand the question, but as long as you put your code in between the IDE "safe" placeholders, changes made to the setup code (in the STM32CubeIDE) aren't lost, like in:
/* USER CODE BEGIN 2 */
MainApp();
/* USER CODE END 2 */
Doing so you don't need to write the trampoline code (and the associated code) every time.
BTW: A ST employee, in this very forum, told me about that the main.c file is going to be always needed.
2025-05-13 8:42 AM
I didn't see that you skipped out early in main.c, after the hardware initialization. I let it run until the user code loop under the OS, and work from there.
I'd still like that C++ option for main.c, though.
Thanks