Skip to main content
Senior III
March 14, 2025
Solved

IAR Error[Li006] 'duplicate definitions' - but not on CubeIDE

  • March 14, 2025
  • 3 replies
  • 2141 views

I'm trying to move my project from CubeIDE to IAR 9.20.4

For some reason I'm gettin Linker Error[Li006] duplicate definitions.

With CubeIDE I'm able to compile and debug/download with no issue.

I know the error is due to the fact I'm having variables on the .h files included in various .c files that are not set as external. 

The question is why CubeIDE ignore this issue and the IAR do not?

Best answer by nico23

You're right,

In the CubeIDE it is defined the flag -fcommon for the compiler

Is there a way to set it in IAR as well?

3 replies

Andrew Neil
Super User
March 14, 2025

@nico23 wrote:

I know the error is due to the fact I'm having variables on the .h files included in various .c files that are not set as external. 


So don't do that, then!

 


@nico23 wrote:

The question is why CubeIDE ignore this issue 


It's not the IDE;  it's the compiler - ie, GCC.

GCC does (did?), indeed, have the option to do this.

You didn't say what CubeIDE version you're using - that would dictate the GCC version.

 

PS:

See: https://community.st.com/t5/stm32cubeide-mcus/multiple-definition-error-after-stm32cubeide-1-9-0-update/m-p/130148/highlight/true#M4955

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
nico23Author
Senior III
March 14, 2025

@Andrew Neil wrote:

@nico23 wrote:

I know the error is due to the fact I'm having variables on the .h files included in various .c files that are not set as external. 


So don't do that, then!

 

 It's legacy code. I didn't wrote it.

 

 


@nico23 wrote:

The question is why CubeIDE ignore this issue 


It's not the IDE;  it's the compiler - ie, GCC.

GCC does (did?), indeed, have the option to do this.

You didn't say what CubeIDE version you're using - that would dictate the GCC version.


I'm using CubeIDE 1.18 (from what I understand it's using GNU Tools 13.3.rel1)

Ozone
Principal
March 14, 2025

First, some code / headers is toolchain-specific,
For IAR, this is "_ICC" if I remember correctly.
So, look for instances of "#ifdef _ICC" or "#ifndef _ICC" vs. "#ifdef GCC" surrounding the problematic code.

> I know the error is due to the fact I'm having variables on the .h files included in various .c files that are not set as external. 

Not sure what you are doing.
While defining variable in .h files is not strictly forbidden, it is very bad practice.
You can declare them as often as desired, but define them only once.
And a linker error is the result of defining it more than once.

As a side note, IAR WB has a certain "feature" to define a "pre include", i.e. an include that is always included first.
This might be preset to a default when creating the project.
I would remove any such entry, as it is incompatible with all other toolchains..

nico23Author
Senior III
March 14, 2025

@Ozone wrote:

While defining variable in .h files is not strictly forbidden, it is very bad practice.


That's the thing. The code defines the variables in the .h file and in various .c file.

For istance I have a struct bed {} in the main.h and struct bed signal in both main.c and task.c

The CubeIDE doesn't seem to bother, instead IAR raises Linker Error[Li006]

Ozone
Principal
March 14, 2025

I would not suspect an issue with gcc, which is quite good. Or IAR, for that matter.
Rather, with the project setup.

I would recommend to check all project sources for occurences/definitions/declarations of this variable.
And especially the map file, which *.o files finally export the same symbol.

Perhaps you have added the same (or similiar) file twice to the project, or two files that don't go together in the same project.

CTapp.1
Senior III
April 28, 2025

The use of something like:

int x;

within a header file is, according to the C Standard, a tentative definition.

Any tentative definition for which an actual definition does not exist within a translation unit becomes a definition at the end of the translation unit when it is compiled. This means that the above use within a header file does result in multiple definitions of x if the header file is included in multiple translation units.

It is therefore perfectly reasonable for IAR to issue a diagnostic, but the standard does not require this behaviour (it is a link-time issue). GCC will do the same with the default -fno-common, but not with -fcommon.

As @Andrew Neil says above, it really is much better to use extern.

All posts are made in a personal capacityMISRA C++ ChairMISRA C WG MemberDirector The MISRA Consortium Limited (TMCL)