2025-02-08 07:59 PM
Hi all,
I transfer development from STM32CubeIDE to VS code with STM32CubeCLT and STM32CubeMX.
By default, the CMake project generated by CubeMX uses C language, but my target language, which includes C++ modules, is supported.
I wonder how to add a cpp module to that to make the project by CubeMX or manually change it.
Thank you all for reading.
Solved! Go to Solution.
2025-02-08 10:50 PM - edited 2025-02-08 10:53 PM
create a new CMake project with STM32CubeMX
open vs code with STM32 extension, import that CMake project.
Dependening on how often you expect to re-generate the code from STM32CubeMX, you may
a) rename main.c to main.cpp, or
b) leave main.c and add some new .hpp and .cpp files.
a) rename main.c to main.cpp
rename main.c to main.cpp,
change the file name main.c to main.cpp in cmake\stm32cubemx\CMakeLists.txt,
add C++ as a language to CMakeLists.txt:
add some test code to main.cpp depending on your board like
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "vector"
/* USER CODE END Includes */
...
/* Infinite loop */
/* USER CODE BEGIN WHILE */
std::vector v = {1, 2, 3, 4, 5};
while (1)
{
for (auto i : v)
{
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
HAL_Delay(i * 100);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
build and debug (run).
b) leave main.c
Add new files, Inc/main.hpp and Src/main.cpp to your project which act as a glue code, like so:
#ifndef __MAIN_HPP
#define __MAIN_HPP
#include <main.h>
#ifdef __cplusplus
extern "C" {
#endif
void setup(void);
void loop(void);
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
implement setup and loop in main.cpp to your like:
#include <main.hpp>
#include <iostream>
#include <string>
#include <vector>
std::vector v = {1, 2, 3, 4, 5};
void setup(void)
{
std::string text = "Hello, World!";
std::cout << text << std::endl;
text += " How are you?";
std::cout << text << std::endl;
}
void loop(void)
{
for (auto i : v)
{
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
HAL_Delay(i * 100);
}
}
call setup and loop from main.c:
/* USER CODE BEGIN Includes */
#include "main.hpp"
/* USER CODE END Includes */
...
/* Infinite loop */
/* USER CODE BEGIN WHILE */
setup();
while (1)
{
loop();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
edit CMakeLists.txt as above:
Buid & Debug (Run).
Note: Too see the iostream output you need, as always, to redirect stdout to an USART ...
hth
KnarfB
2025-02-08 10:50 PM - edited 2025-02-08 10:53 PM
create a new CMake project with STM32CubeMX
open vs code with STM32 extension, import that CMake project.
Dependening on how often you expect to re-generate the code from STM32CubeMX, you may
a) rename main.c to main.cpp, or
b) leave main.c and add some new .hpp and .cpp files.
a) rename main.c to main.cpp
rename main.c to main.cpp,
change the file name main.c to main.cpp in cmake\stm32cubemx\CMakeLists.txt,
add C++ as a language to CMakeLists.txt:
add some test code to main.cpp depending on your board like
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "vector"
/* USER CODE END Includes */
...
/* Infinite loop */
/* USER CODE BEGIN WHILE */
std::vector v = {1, 2, 3, 4, 5};
while (1)
{
for (auto i : v)
{
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
HAL_Delay(i * 100);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
build and debug (run).
b) leave main.c
Add new files, Inc/main.hpp and Src/main.cpp to your project which act as a glue code, like so:
#ifndef __MAIN_HPP
#define __MAIN_HPP
#include <main.h>
#ifdef __cplusplus
extern "C" {
#endif
void setup(void);
void loop(void);
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
implement setup and loop in main.cpp to your like:
#include <main.hpp>
#include <iostream>
#include <string>
#include <vector>
std::vector v = {1, 2, 3, 4, 5};
void setup(void)
{
std::string text = "Hello, World!";
std::cout << text << std::endl;
text += " How are you?";
std::cout << text << std::endl;
}
void loop(void)
{
for (auto i : v)
{
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
HAL_Delay(i * 100);
}
}
call setup and loop from main.c:
/* USER CODE BEGIN Includes */
#include "main.hpp"
/* USER CODE END Includes */
...
/* Infinite loop */
/* USER CODE BEGIN WHILE */
setup();
while (1)
{
loop();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
edit CMakeLists.txt as above:
Buid & Debug (Run).
Note: Too see the iostream output you need, as always, to redirect stdout to an USART ...
hth
KnarfB
2025-02-09 12:49 AM
For the First option: a) rename main.c to main.cpp
I have tried and I confirmed it worked as expected for C++, but When we generated code again by CubeMX, main.c and main.h shall also created.
I think we can try solution number 2 (leave main.c) for creating main.cpp and main.hpp. => It is also working and I want to share from my case, CMakeLists.txt shall be:
enable_language(C CXX ASM)
...
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# Add user sources here
Core/Src/main.cpp
)
Thank @KnarfB for your reply. I think this topic can be closed.