Multiple Definition Errors when linking

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I have written many projects using Atmel Studio 4 and 6.2.  My practice is to use a well structured modular approach, with modules comprising .c and .h files.  Public variables and functions are defined in the .c file and are declared as extern in the .h file.  To avoid multiple declarations, I always enclose all .h declarations in [#ifndef _MODULE_H, define _MODULE_H, {declarations}, #endif] structures.

 

I'm using Atmel Studio 6.2 because I'm in the process of getting the project ready to transfer to the client, and want to remain on the IDE version that's been successful during development up to now, if possible.  So I haven't upgraded to AS7 yet.  I'm using the native GNU toolset.

 

Adding a couple more modules, I've just begun the get Multiple Definitions errors which make no sense to me.  An example of the relevant output is given below:

 

  Building target: Proj.elf
  Invoking: AVR/GNU Linker : 4.8.1
  "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-gcc.exe" -o Proj.elf  accel.o eeprom.o flash.o function.o gnss.o gsm.o inputs.o panel.o tcp.o power.o rtc.o serial_gsm.o spi.o time.o uid.o adc.o commands.o console.o i2c.o status.o main.o timebase.o atomic.o   -Wl,-Map="Proj.map" -Wl,-u,vfprintf -Wl,--start-group -Wl,-lprintf_flt -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -Wl,--defsym=__stack=0x2FFF -mmcu=atxmega64a3u  
  tcp.o: In function `tcp_init':
C:\Path\Working\default/.././tcp.c(79,1): error: multiple definition of `tcp_init'
  panel.o:C:\Path\Working\default/.././tcp.c:79: first defined here
  tcp.o: In function `tcp_connect':
C:\Path\Working\default/.././tcp.c(94,1): error: multiple definition of `tcp_connect'
  panel.o:C:\Path\Working\default/.././tcp.c:94: first defined here
  tcp.o: In function `tcp_init':
C:\Path\Working\default/.././tcp.c(79,1): error: multiple definition of `tcp_connected'
  panel.o:C:\Path\Working\default/.././tcp.c:79: first defined here
  tcp.o: In function `tcp_disconnect':
C:\Path\Working\default/.././tcp.c(217,1): error: multiple definition of `tcp_disconnect'
  panel.o:C:\Path\Working\default/.././tcp.c:217: first defined here
  tcp.o: In function `tcp_send':
C:\Path\Working\default/.././tcp.c(239,1): error: multiple definition of `tcp_send'
  panel.o:C:\Path\Working\default/.././tcp.c:239: first defined here
collect2.exe(0,0): error: ld returned 1 exit status
  make: *** [Proj.elf] Error 1
  The command exited with code 2.
 Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "Proj.cproj" -- FAILED.
Done building project "Proj.cproj" -- FAILED.

Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

If I comment out the #include "tcp.h" from one module, the errors disappear, but then I can't access tcp functions from that module.  The errors make no sense to me, there are no duplicate definitions, and the tcp.h file only includes extern declarations, not definitions.  Futhermore, the first error, shows correctly that the function `tcp_init' is defined in line 79, but it is not defined elsewhere.  And the third error, complaining that the variable `tcp_connected' is defined on the same line 79 is patently false.  That variable is defined on line 44 and is declared as extern in tcp.h.

 

I have searched the web and this forum for similar issues, and the most similar post recommends a tutorial at https://www.avrfreaks.net/forum/tut-modularizing-c-code-managing-large-projects?name=PNphpBB2&file=viewtopic&t=48535, which I've read and which already describes the standard structure I use.

 

Has anyone encountered similar issues with large multi-module projects like this?  Is there a limit on the number of modules that can be linked?  Is there an issue with the scope of #define _MODULE_H definitions, which may cause my multiple declaration protection to fail?  Anyone got any other thoughts on why this is occurring and what I can try to solve it?

 

For confidentiality reasons, I can't publish or share the code, but I may be able to post redacted extracts if that will help.

 

Many thanks in advance to anyone taking the trouble to read or respond to this.  It's most frustrating!

 

This topic has a solution.

Electronic components work on the principle of smoke; I know this because when I let the smoke out, they stop working. Also, sanity is over-rated.

Last Edited: Wed. Dec 9, 2015 - 10:25 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Looks like panel.c is #include-ing tcp.c.  You really shouldn't ever including any .c files.  Only .h files.

 

Have a look at this for hints on how to structure large projects:

https://www.avrfreaks.net/forum/tut-modularizing-c-code-managing-large-projects?page=all

https://raw.githubusercontent.com/abcminiuser/avr-tutorials/master/ManagingLargeProjects/Output/ManagingLargeProjects.pdf

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

billysugger wrote:
and the tcp.h file only includes extern declarations, not definitions.

Can you show that? As I actually said in a thread yesterday if one made the error of using:

// tcp.h

int tcp_init(int, long, char) {}

rather than the intended:

// tcp.h

int tcp_init(int, long, char) ;

that could explain what you are seeing.

 

However I am a bit confused by your error message anyway:

  tcp.o: In function `tcp_init':
C:\Path\Working\default/.././tcp.c(79,1): error: multiple definition of `tcp_init'
  panel.o:C:\Path\Working\default/.././tcp.c:79: first defined here

yes, that is saying that there are inplementations of tcp_init() in both tcp.c and panel.c but notice the line numbers? They are BOTH 79. I would say that was just a curious co-incidence until you get to:

  tcp.o: In function `tcp_connect':
C:\Path\Working\default/.././tcp.c(94,1): error: multiple definition of `tcp_connect'
  panel.o:C:\Path\Working\default/.././tcp.c:94: first defined here

That seems to be suggesting it's at both line 94 in tcp.c and panel.c

 

Could it be that the contents of tcp.c have accidentally been copied into panel.c ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you kick off a build, Studio starts Make, and the makefile has as one of its first targets to generate dependencies. These will be placed in .d files in a .dep subdirectory. They are text files, with lines on the form

 

targetFile : dependencyFile1 dependencyFile2 ...

If you find something like

 

whatever.c : somethingelse.c

i.e. a .c file being dependent on another .c file you may have found the perpetrator. the file whatever.c probably #includes somethingelse.c . It should not.

 

If somethingelse.c is among the list (in the makefile) of source files to be compiled, then the code will be compiled twice. Once as  somethingelse.c, and once as a part of whatever.c. When the linker gets a hold on whatever.o and somethingelse.o it sees double definitions of everything from somethingelse.c. 

 

Another possibility is to simply search the entire project for #includes. If you find an include of a .c file you've likely found the perpetrator.

 

For the ambitious it should be noted that Studio supports searches using regular expressions. You could then search for #includes that specifically includes a .c file. I won't come up with the regex out of my head, but might verify what I think it should be tonight. Or I might just forget about this in three minutes...

 

Before I forget...: You could of-course use grep on a command line, instead of Studios search.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Wed. Dec 9, 2015 - 10:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
 I am a bit confused by your error message anyway:

  tcp.o: In function `tcp_init':
C:\Path\Working\default/.././tcp.c(79,1): error: multiple definition of `tcp_init'
  panel.o:C:\Path\Working\default/.././tcp.c:79: first defined here

yes, that is saying that there are inplementations of tcp_init() in both tcp.c and panel.c but notice the line numbers? They are BOTH 79. I would say that was just a curious co-incidence until you get to:

But is it not the case that the line number reported is the line in the file in which the error was actually found?

 

That is the way you'd normally want it, with normal use of headers: if the error is in the header, you'd want the message to give you the name of the header, and the line number within that header?

 

In this case, it's a .c file instead of a header - so you'd expect both messages to point to the same place in tcp.c - wouldn't you?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff,

I'm betting two stouts that it's about mistakenly including a .c file.

 

The Red Lion next Saturday is okay with me?   ;-)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin

Looks like panel.c is #include-ing tcp.c.  You really shouldn't ever including any .c files.  Only .h files.

Argh! A horrid typo! That's what you get when you're coding at 2am! Can't see the wood for the trees.

 

I'm betting two stouts that it's about mistakenly including a .c file.

JohanEkdahl, enjoy your pint!

 

Thanks to all for looking at this, another humbling experience on AVR Freaks!

 

Electronic components work on the principle of smoke; I know this because when I let the smoke out, they stop working. Also, sanity is over-rated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

billysugger wrote:

I'm betting two stouts that it's about mistakenly including a .c file.

JohanEkdahl, enjoy your pint!

 

Thanks to all for looking at this, another humbling experience on AVR Freaks!

 

Blatant advertising, all smilies apply:

 

SEEKING DONATIONS

 

Dear Fellows, I am looking for donations towards the following:

 

1 piece round-trip train-ticket Lund -- Copenhagen Airport

1 piece round trip flight-ticket Copenhagen Airport --  Heathrow London

1 piece round trip train ticket Heathrow - Stansted Mountfitchet

1 cab fare Stansted Mountfitchet - The Red Lion, Finchingfield

1 plate of fish'n'chips

3 cl Scapa or other fine whiskey

3 cl Scapa, Highland Park or other malt whiskey

3 cl Scapa or other whisky

3 cl Scapa or burbon

3 cl Scapa or whatever

3 cl whatever

Possibly another plate of chiff'n'fips

1 nights stay at The Red Lion

1 gallon of coffee

1 cab fare The Red Lion, Finchingfielt - Stansted Mountfitchet

1 personal assistant to help me with all those return tickets and anything else needed to get me back home.

 

Thank you!

 

PS. Don't worry about the amount of beverage above - I am in the habit of watering my malt slightly. (-:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
 I am in the habit of watering my malt

[/quote]

 

Philistine!!

 

surprise

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Dec 9, 2015 - 01:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dunno what's wrong with that [ /quote ] tag ?!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Dec 9, 2015 - 01:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can thank the WYSINWYG editor.

 

Here's what your raw post looks like when copy/pasted to a plain text editor (when I 'quote' your above post, hence the wrapping quote by you):

 

 

Note the placement of the offending [ / quote ].  It has been absorbed and mangled with two separate < span > < / span > tag pairs within a  < p > < /p > tag pair, but needs to be wholly outside to match the [ quote = anweil ] opening tag.

 

This should work:

 

 

 

EDIT: and indeed it does:

 

awneil wrote:

JohanEkdahl wrote:
 I am in the habit of watering my malt

 

Philistine!!

 

surprise

 

How did it happen?  Who knows.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Dec 9, 2015 - 02:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan, I'll pop for first fish and chips.  You take Paypal? ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
1 nights stay at The Red Lion

I have possibly bad news about the Red Lion. Subject to a pending planning application it may be about to change usage from public house to a private dwelling. (and would be the second pub in the village to head down that route). As it happens I wouldn't have recommended it these days anyway as the owners are ... well OK, perhaps the least said about that the better. Anwyay, not entirely surprised it's closing down though!

 

As to the whisky/whiskey: I think you are going to have to learn to love Laphroaig, Glenfarclas 105 or Jameson at the present time :-)

 

(the Scots would presumably declare war if I admitted it, but I quite like whisky on ice - so OK, shoot me!)

 

PS with no lodging in the village you may find yourself sharing a room with a couple of fairly fierce Bengal cats. You have been warned.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PS with no lodging in the village you may find yourself sharing a room with a couple of fairly fierce Bengal cats. You have been warned.

Johan, here's some research material to help you survive:

https://www.avrfreaks.net/forum/ultimate-cat-video

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
You can thank the WYSINWYG editor.

There are many things I'd like to do to the so-called "WYSIWYG" editor - but thanking it is certainly not one of them!!

 

angry

 

How did it happen?  Who knows.

But this kind of thing has happened before  - one such occurrence managed to turn an entire thread bold!!

 

surprise

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The "other fine whiskey" does OD-COURSE include Laphroaig. Also Talisker. I once had the pleasure to sip on a 18 y.o. Glenlivet which was much better than I had anticipated. The Irish are OK on some occasions - poring them into a good coffee is doing a disfavor to both beverages.

 

So, any pubs at all left in Finchingfield?

 

(thought it OK to derail for some social smalltalk since the matter at hand is solved..)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, any pubs at all left in Finchingfield?

Just 2 left if the Red Lion goes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Only two.. Poor Finchingfield souls.. ;-)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl

 

I once had the pleasure to sip on a 18 y.o. Glenlivet which was much better than I had anticipated.

 

I prefer the 15-year old Glenlivet, far smoother. On my last tour of the distillery, we sampled 12- 15- and 18-yo and the 15 was definitely the best to me.

 

And as for watering malt whiskey, if you know anything about the stuff, it comes out of the cask at 65% and is watered to 40% for bottling, (it's a UK legal requirement, except you can buy bottled cask strength direct from the distillery - it's gross btw). The blender blends for the target taste when 10-20% water is added to the bottled 40%. So any Scotch drinker who knows what he's doing will add a little water, more or less to taste for the particular variety. Warming a sip on the tongue releases the volatiles, which is an essential part of the whiskey drinking experience. Adding ice is pure madness (popular in America), and that not only cools the liquor, making the volatiles harder to evolve, but it means the strength changes as the ice melts. Mad, mad, MAD! But they drink dark beer cold too, maybe they just can't take the taste of good alcoholic beverages and have to numb their taste buds. That's what Budweizer's for anyway.

 

I know a nice little hotel in Angus with literally HUNDREDS of whiskeys. It's a dangerous place to stay...

Electronic components work on the principle of smoke; I know this because when I let the smoke out, they stop working. Also, sanity is over-rated.

Last Edited: Thu. Dec 10, 2015 - 12:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A drop or two of room temperature water goes into my glass of scotch after pouring.  Not tap water, for heaven's sake.  Preferably from the fresh water spring on my dad's farm.

 

And never on the rocks.  Ice is for lemonade.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]