user1570730
user1570730

Reputation: 65

Xcode duplicate symbol error

I am getting "Apple Mach-O Linker (Id) Error":

ld: duplicate symbol _matrixIdentity in /BlahBlah/Corridor.o and /Blahblah/Drawable.o for architecture i386

The class "Corridor" is extending the class "Drawable" and "_matrixIdentity" is defined and implemented in a file "Utils.h". Here are top lines from my header files:

Drawable.h

#import <Foundation/Foundation.h>
#import "Utils.h" 
@interface Drawable : NSObject
...

Corridor.h

#import <Foundation/Foundation.h>
#import "Drawable.h"
@interface Corridor : Drawable
...

I have already checked if there are any ".m" imports instead of ".h", everything is correct. Any idea, what could cause this problem?

EDIT: posting code from "Utils.h"

#import <Foundation/Foundation.h>    
...
#pragma mark -
#pragma mark Definitions

typedef float mat4[16];

#pragma mark -
#pragma mark Functions
void matrixIdentity(mat4 m)

{
m[0] = m[5] = m[10] = m[15] = 1.0;
m[1] = m[2] = m[3] = m[4] = 0.0;
m[6] = m[7] = m[8] = m[9] = 0.0;
m[11] = m[12] = m[13] = m[14] = 0.0;
}
...

I am only referencing to "mat4" definition in my both classes' methods. Also, "matrixIdentity" is just the first function in this file, may be the problem is not in implementation.

Upvotes: 3

Views: 17878

Answers (5)

rounak
rounak

Reputation: 9397

In my case, I was implementing a function in the header file itself. Adding a static inline keyword before the function fixed the error for me.

Upvotes: 0

Deepak Kumar
Deepak Kumar

Reputation: 39

Use -force_load for one library in Other linker flags .. that solved the prob for me once

Upvotes: 0

user529758
user529758

Reputation:

Two solutions to your problem:

  1. Declare only void matrixIdentity(mat4 m); in the header file and then implment the actual code in a corresponding c/m file.
  2. Make your function in the header file inline (that's the technique Apple uses)

    inline void matrixIdentity(mat4 m) { ...

Upvotes: 2

booiljoung
booiljoung

Reputation: 814

C/C++/Objective-C diff with Java, C#, Ruby, Python...

Divide files.

header & mm

Do not use #include (may include many times)

Use #import... (include once)


Utils.h

#ifndef __utils_h__ // <<< avoid multiple #include
#define __utils_h__ // <<< avoid multiple #include
#import <Foundation/Foundation.h>    
...
#pragma mark -
#pragma mark Definitions

typedef float mat4[16];

#pragma mark -
#pragma mark Functions
extern void matrixIdentity(mat4 m);

#endif // __utils_h__ <<< avoid multiple #include

Utils.mm

#import "Utils.h"

void matrixIdentity(mat4 m)
{
m[0] = m[5] = m[10] = m[15] = 1.0;
m[1] = m[2] = m[3] = m[4] = 0.0;
m[6] = m[7] = m[8] = m[9] = 0.0;
m[11] = m[12] = m[13] = m[14] = 0.0;
}
...

Upvotes: 2

marko
marko

Reputation: 9159

From your description, utils.h declares and implements a variable, the implementation of which is compiled in corridor.h and Drawable.h by virtue of utils.h being included in both (indirectly through Drawable.h in the case of Corridor.h). Thus both compilation units contain an implementation for _matrixIdentity, and the linker complains.

Move the implementation of _matrixIdentity into a new module utils.m to ensure there is only one definition of the symbol.

Upvotes: 1

Related Questions