0

I am trying to compile my program with this makefile but the linker is giving me some fuss saying that there are duplicate symbols. I tried playing with this makefile but I haven't had much luck. My program only has three files, pdp429.c, instructions.c, and global.h. Any help is appreciated thanks!

Here are the errors, (there are 46 of the "duplicate symbol" errors) "duplicate symbol _MASK_IN in: pdp429.o instructions.o ld: 46 duplicate symbols for architecture x86_64 collect2: ld returned 1 exit status make: *** [pdp429] Error 1"

CFLAGS = -O0 -pg -ggdb3 -Wall

all:    pdp429

pdp429: pdp429.o instructions.o
    gcc $(CFLAGS) pdp429.o instructions.o -o pdp429

pdp429.o: pdp429.c global.h
    gcc $(CFLAGS) pdp429.c -c

instructions.o: instructions.c global.h
    gcc $(CFLAGS) instructions.c -c

clean:
    rm -f *.o pdp429
Sean
  • 541
  • 7
  • 26
  • 1
    So what are the actual errors, and where are those symbols actually defined ? It may not be related to your makefile at all – nos Dec 06 '13 at 18:44
  • ld: 46 duplicate symbols for architecture x86_64 collect2: ld returned 1 exit status make: *** [pdp429] Error 1 – Sean Dec 06 '13 at 18:48
  • 1
    According to your edit, one of those duplicate symbols is named `_MASK_IN` Is that correct ? Now - which of your 3 files is `_MASK_IN ` defined in, and how is it defined. Note: Show us the entire line in the file where you have defined `_MASK_IN`. – nos Dec 06 '13 at 18:56
  • The message is pretty large. It is saying I have duplicate symbols in my object files. I was thinking it was because I am including global.h in both of my c files but I put guards up on my global.h such as "#ifndef _GLOBAL_H_..." – Sean Dec 06 '13 at 18:58
  • _MASKI_IN is defined in global.h as follows "short MASK_IN = 0x0001;" – Sean Dec 06 '13 at 19:02
  • @Sean: What is `_MASK_IN`? How and where is it defined? – AnT stands with Russia Dec 06 '13 at 19:02
  • @Sean right. So when you include that header file in both of your .c file, both of them will contain the `MASK_IN` variable - thus they are duplicated. See http://stackoverflow.com/questions/1433204/how-do-i-share-a-variable-between-source-files-in-c-with-extern-but-how – nos Dec 06 '13 at 19:05
  • @Sean: Is `MASK_IN` intended to be a manifest constant? Or a global variable? – AnT stands with Russia Dec 06 '13 at 19:07
  • It is intended to be a manifest constant. I added "static" and it solved the issue. I'm still kind of a C noobie so thanks for teaching me something today! – Sean Dec 06 '13 at 19:21
  • @Sean: If it is intended to be a manifest constant, make it `static const`. But in C it is usually a better idea to use `#define` or `enum`, not `static const`. – AnT stands with Russia Dec 06 '13 at 19:22
  • @Sean if this question is solved, tick the correct answer, or if no-one has answered it, you should answer and accept it. – Joe Dec 06 '13 at 19:25
  • OK thanks I just did. I was always a lurker and finally asked a question so the protocol is still new to me. Appreciate the help – Sean Dec 06 '13 at 19:30

2 Answers2

1

You do not provide some critical information, but the immediate guess that you managed to define some entities with external linkage (i.e. variables or functions) in your globals.h header file. Since your globals.h is probably included into both of your *.c files, you end up with multiple definition error.

The MASK_IN is the obvious candidate, judging by the error messages. What is MASK_IN and how and where is it defined?

EDIT: So, here you go. Your MASK_IN is defined in globals.h as short MASK_IN = 0x0001;. This will certainly cause the multiple definition error. It looks like you actually tried to define a named constant. If so, the in C language one would typically use #define to define manifest constants, i,.e. do

#define MASK_IN 0x0001

but if you really want to use a named object, then for scalar type the best approach would be to do

static const short MASK_IN = 0x0001;

in the header file.

If your MASK_IN is intended to be a global variable (not a constant), then your only option is to use

extern short MASK_IN;

in the header file and

short MASK_IN = 0x0001;

in one (and only one) of the .c files.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • I added "static" and it solved the issue. I'm still kind of a C noobie so thanks for teaching me something today! – Sean Dec 06 '13 at 19:22
  • @Sean: If it is intended to be a manifest constant, make it `static const`. But in C it is usually a better idea to use `#define` or `enum`, not `static const`. – AnT stands with Russia Dec 06 '13 at 19:23
  • @Sean: The effect of `static` on a variable declared in a header file is to make it file-local. Which means that each file which includes that header gets its own copy of the variable. – Zan Lynx Dec 06 '13 at 19:35
  • @ZanLynx Okay I see. I went back and replaced static with #define – Sean Dec 06 '13 at 19:36
0

You still have not provided the information people have asked for, but I'm going to go out on a limb and say:

  1. You've defined _MASK_IN inside global.h
  2. You've included global.h in multiple source files.

This would lead to the symbol being multiply defined. You should extern short _MASK_IN; in your header, and actually define it in a source file with short _MASK_IN = 0x0001;. Or better yet, assuming it's constant, simply #define it in a header file instead.

The #ifndef guards your comment says you use do not help because from one source file to the next, those guards are cleared. The #define is only valid within the source being compiled at any point in time.

mah
  • 39,056
  • 9
  • 76
  • 93