cancel
Showing results for 
Search instead for 
Did you mean: 

How to fix "multiple definition of `errno"'?

DK.7
Senior

I try to create a new project, nothing is written in main.c! It is a first check after setting up 'LWIP', 'SDIO' and Freertos in the GUI and got this mistake!

multiple definition of `errno'; ./Middlewares/Third_Party/LwIP/system/OS/sys_arch.o:/home/denis/STM32CubeIDE/workspace_1.9.0/FreeRtos_SDIO_Web/Debug/../Middlewares/Third_Party/LwIP/system/OS/sys_arch.c:45: first defined here

STM32CubeIDE Version: 1.9.0

PS - This error not appear then I was on STM32CubeIDE Version: 1.8.0

22 REPLIES 22
Pavel A.
Evangelist III

"extern" is not good at all. The C library can be thread-enabled and define its errno like this:

struct thread_context_s {
  ......
  int m_errno;
};
extern thread_context_s * thread_ctx_ptr;
#define errno (thread_ctx_ptr->m_errno)

Thank you for the explanation but, I am not from those who can change rules in the standard libraries of 'C'.

How do I need to do it right according your mention?

Below on the screenshots, I showed the current state.0693W00000Lw5ApQAJ.png0693W00000Lw5AaQAJ.png

Pavel A.
Evangelist III

> How do I need to do it right according your mention?

Just follow the "single definition" rule: #include <errno.h> everywhere, remove any other definitions of errno.

LwIP is not a "standard library", it is a add-on component. It is not in position to override errno for the rest of application.

heveskar
Senior

Don't you think it is a bug in LwIP configuration settings in the Cube? I think we should be able to remove the define LWIP_PROVIDE_ERRNO and set LWIP_ERRNO_STDINCLUDE or define LWIP_ERRNO_INCLUDE to <sys/errno.h>. Those settings could be in Key Options of the LwIP stack.

I noticed that this fixes the issue, in cc.h:

//#define LWIP_PROVIDE_ERRNO
#define LWIP_ERRNO_INCLUDE  <sys/errno.h>

But this is lost with every code re-generation which is not very good, is it.

@Community member​ 's solution of building with -fcommon also works for me.

Karel

> #define LWIP_ERRNO_INCLUDE <sys/errno.h>

Just <errno.h> , not <sys/errno.h> or something else.

 > But this is lost with every code re-generation which is not very good, is it.

File cc.h is part of libraries (LwIP) that get copied over to generated source tree.

If you choose to create references to the libraries instead of copying every time, your changes in cc.h or other library files should stay.

Unfortunately the life is not ideal.

<errno.h> is not working for me as it probably uses lwip/errno.h. Only <sys/errno.h> solved the compilation issue, that's why I wrote it. Maybe you are right that it is not clean, probably the compilation flag method is better.

As for the second part, I did not know that library files can be referenced and not copied, thank you for that.

Life is not ideal especially if one has to use the ST products that seem to be always full of bugs, it just never ends.

I think that my point still stands, in cube there should be setting which errno to use. Or just do it somehow that the project can be configured from cube and built properly, without editing library files.

0693W00000LxZFrQAN.png

Jan's answer is the real answer. The image is only for those, who cannot read...

Pavel A.
Evangelist III

@Piranha​ Why? There should be one and only one definition of errno, and it is provided by the newlib's include file. -fcommon is not relevant here.

Looks like LwIP has its own errno.h that makes a mess for the OP...

My idea was more like: "If one accepts -fcommon as an answer, then one should select the comment which informed about it, not the one, which put a screenshot of it."

The lwIP stack has an option to provide alternate errno implementations, but that option is disabled by default. As almost always, the problem is not in the lwIP, but in ST's code. As often, they have written a code, which is not necessary at all. Those 3 lines and include in file sys_arch.c should just be removed. HAL/Cube developers create such a ridiculous problems all the time, because they do not understand what they are doing. "Re-initializing" clock calibration values is another spectacular example of not understanding what and why they are doing...