cancel
Showing results for 
Search instead for 
Did you mean: 

Using STM32CubeMX generate code for STM32CubeIDE and than change main.c to main.cpp, and build project will show up undefined reference to 'main' error.

jcRuan
Associate II

The error message like as:

Core/Startup/startup_stm32f765vitx.o: In function `LoopFillZerobss':

J:/STM32PRJ/CB_ENV/MS220_F765VI/VIDEOBOARD_V9A/20200520/Debug/../Core/Startup/startup_stm32f765vitx.s:97: undefined reference to `main'

collect2.exe: error: ld returned 1 exit status

make: *** [makefile:47: VideoBoard.elf] Error 1

"make -j8 all" terminated with exit code 2. Build might be incomplete.

How can I solve this problem?

1 ACCEPTED SOLUTION

Accepted Solutions

Hi @alister​ 

​Sorry, I misunderstood what you meant, but i solved this problem, thanks your help.

The setting steps is:

  1. Generate (or regenerate) code.
  2. Mouse click right on the project icon as: 0693W000001cgiFQAQ.png
  3. Select "Convert to C++" item as:0693W000001cgiKQAQ.png
  4. Change main.c to main.cpp( from STM32CubeIDE rename). Don't rename from the Windows file system manually. If regenerate code need to rename again and maybe need to porting old main.cpp to new main.cpp(last rename) again. 0693W000001cgiPQAQ.png
  5. Build project.

View solution in original post

6 REPLIES 6
alister
Lead

Explained https://www.geeksforgeeks.org/extern-c-in-c/ and many other places.

The LoopFillZerobss was indented to call a "C" main. Declare main like this in main.c before you define it, i.e. before the main() function.

extern "C"
{ 
    int main(void); 
} 

Hi @alister​ 

Thanks your replay.

I try to put extern "c" before the main() function but it doesn't work, the error message is the same. the code snippet following:

extern "C"
{
	int main(void)
	{
	  /* USER CODE BEGIN 1 */
 
	  /* USER CODE END 1 */
	
	  /* MCU Configuration--------------------------------------------------------*/
	
	  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	  HAL_Init();
	
	  /* USER CODE BEGIN Init */
	
	  /* USER CODE END Init */
	
	  /* Configure the system clock */
	  SystemClock_Config();
	
	  /* USER CODE BEGIN SysInit */
	
	  /* USER CODE END SysInit */
	
	  /* Initialize all configured peripherals */
	  MX_GPIO_Init();
	  MX_I2C3_Init();
	  MX_SPI3_Init();
	  MX_TIM6_Init();
	  /* USER CODE BEGIN 2 */
	  //sys_main->SysMainInit();//this is cpp function
	  /* USER CODE END 2 */
	
	  /* Infinite loop */
	  /* USER CODE BEGIN WHILE */
	  while (1)
	  {
		  //sys_main->SysMainLoop();//this is cpp function
		/* USER CODE END WHILE */
	
		/* USER CODE BEGIN 3 */
	  }
	  /* USER CODE END 3 */
	}
}

Do I need to modify the compilation settings?

I'm guessing, try declaring it only as extern "C", not defining it.

Is there a main with a C++ mangled name in the linker map file, or what does main look like there?

Are you sure you're compiling/linking the file main's in?

Check https://stackoverflow.com/questions/18137814/loopfillzerobss-has-an-undefined-reference-to-main too.

Hi @alister​ 

I'm not defining it, add extern "c" before function name directly.

I don't found main.o in object.list ,because use main.cpp (i guess), the file content following:

"Application/system/sys_test.o"

"Core/Src/gpio.o"

"Core/Src/i2c.o"

"Core/Src/spi.o"

"Core/Src/stm32f7xx_hal_msp.o"

"Core/Src/stm32f7xx_it.o"

"Core/Src/syscalls.o"

"Core/Src/sysmem.o"

"Core/Src/system_stm32f7xx.o"

"Core/Src/tim.o"

"Core/Startup/startup_stm32f765vitx.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_exti.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi_ex.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.o"

"Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.o"

"Middleware/hdmi_tx/driver/csc.o"

"Middleware/hdmi_tx/driver/hdmitx_cec.o"

"Middleware/hdmi_tx/driver/hdmitx_drv.o"

"Middleware/hdmi_tx/driver/hdmitx_hdcp.o"

"Middleware/hdmi_tx/driver/hdmitx_input.o"

"Middleware/hdmi_tx/driver/hdmitx_sys.o"

"Middleware/hdmi_tx/driver/sha1.o"

I have read this article(in you reply) before asking this questions .

​I think gcc compiler/linking cannot find the main.cpp file, so the error appears.

Using cubeMX generate *.c and *.h code. but in my project had .cpp file, And i want to call cpp function from main.c.

Therefore, I try to change main.c to main.cpp.

And i try another method, i don't changed main.c, and reference from How do I call a C++ function from C? FAQ topic.

try calling c++ function from c, and then show error as:

Core/Src/main.o: In function `main':

J:/STM32 PRJ/CB_ENV/MS220_F765VI/VIDEOBOARD_V9A/20200520/Debug/../Core/Src/main.c:101: undefined reference to `sysInit'

J:/STM32 PRJ/CB_ENV/MS220_F765VI/VIDEOBOARD_V9A/20200520/Debug/../Core/Src/main.c:111: undefined reference to `sysLoop'

collect2.exe: error: ld returned 1 exit status

The project code snippet following.

sys_c_call.h :

 
#ifndef SYS_C_CALL_H_
#define SYS_C_CALL_H_
 
 #ifdef __cplusplus
 #define EXTERNC extern "C"
 #else
 #define EXTERNC
 #endif
 
EXTERNC void sysInit();
EXTERNC void sysLoop();
 
#endif /* SYS_C_CALL_H_ */

​sys_c_call.cpp :

#include "sys_c_call.h"
#include "../../Application/system/sys_main.hpp"
 
APP::SysMain *sys_main = new APP::SysMain();;
 
void sysInit()
{
 sys_main->SysMainInit();
}
 
void sysLoop()
{
 sys_main->SysMainLoop();
}

​main.c :

#include "../../Application/system/sys_c_call.h"
 
        int main(void)
	{
	  /* USER CODE BEGIN 1 */
	  /* USER CODE END 1 */
 
	  /* MCU Configuration--------------------------------------------------------*/
 
	  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	  HAL_Init();
 
	  /* USER CODE BEGIN Init */
 
	  /* USER CODE END Init */
 
	  /* Configure the system clock */
	  SystemClock_Config();
 
	  /* USER CODE BEGIN SysInit */
 
	  /* USER CODE END SysInit */
 
	  /* Initialize all configured peripherals */
	  MX_GPIO_Init();
	  MX_I2C3_Init();
	  MX_SPI3_Init();
	  MX_TIM6_Init();
	  /* USER CODE BEGIN 2 */
	  sysInit();
	  /* USER CODE END 2 */
 
	  /* Infinite loop */
	  /* USER CODE BEGIN WHILE */
	  while (1)
	  {
		  sysLoop();
		/* USER CODE END WHILE */
 
		/* USER CODE BEGIN 3 */
	  }
	  /* USER CODE END 3 */
	}

>I'm not defining it, add extern "c" before function name directly.

You're defining main. I'm guessing though, and I expect it'd make no difference.

//declare
extern "C"
{
  int main(void);
}
 
//define
int main(void)
{
<snip>
}

>I don't found main.o in object.list ,because use main.cpp (i guess), the file content following

You'd said in the post description you'd changed main.c to main.cpp. How did you do that. If it was _in_ Eclipse's Project Explorer, or if you hacked its .project file, that might be fine. But if you renamed it outside the IDE, e.g. in Windows Explorer, then the project's not going to find it and perhaps even remove it from the .project. Check the Project Explorer and rename main.c if it's there or add main.cpp if it isn't.

Hi @alister​ 

​Sorry, I misunderstood what you meant, but i solved this problem, thanks your help.

The setting steps is:

  1. Generate (or regenerate) code.
  2. Mouse click right on the project icon as: 0693W000001cgiFQAQ.png
  3. Select "Convert to C++" item as:0693W000001cgiKQAQ.png
  4. Change main.c to main.cpp( from STM32CubeIDE rename). Don't rename from the Windows file system manually. If regenerate code need to rename again and maybe need to porting old main.cpp to new main.cpp(last rename) again. 0693W000001cgiPQAQ.png
  5. Build project.