Apple Mach-O Linker错误,我不知道为什么

时间:2013-12-21 03:58:46

标签: ios objective-c linker-errors

我正在制作一个简单的游戏并遇到了问题。 我收到了这个错误:

重复符号_vertices:     / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/ViewController.o     / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/Block.o 重复符号_indices:     / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/ViewController.o     / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/Block.o ld:2个用于体系结构i386的重复符号 clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)

我尝试过开始一个新项目并再次尝试,但还没有任何工作。 我有一个C ++背景,有点刚刚跳进Objective-C,所以可能就是这样。

这是我的代码:

ViewController.m:

#import "ViewController.h"

@interface ViewController () {
    Block *testBlock;
}

@property (strong, nonatomic) EAGLContext *context;

- (void)setupGL;
- (void)teardownGL;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableMultisample = GLKViewDrawableMultisample4X;
    view.drawableStencilFormat = GLKViewDrawableStencilFormatNone;
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    [EAGLContext setCurrentContext:self.context];

    self.preferredFramesPerSecond = 60;
    self.pauseOnWillResignActive = YES;
    self.resumeOnDidBecomeActive = NO;

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
    tapGesture.numberOfTapsRequired = 2;
    [self.view addGestureRecognizer:tapGesture];

    [self setupGL];
}

- (void)dealloc
{
    [self teardownGL];

    if ([EAGLContext currentContext] == self.context)
        [EAGLContext setCurrentContext:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    if ([self isViewLoaded] && ([[self view] window] == nil))
        self.view = nil;

    [self teardownGL];

    if ([EAGLContext currentContext] == self.context)
        [EAGLContext setCurrentContext:nil];

    self.context = nil;

    // Dispose of any resources that can be recreated.
}

- (void)setupGL
{
    [EAGLContext setCurrentContext:self.context];

    testBlock = [[Block alloc] initWithType:BT_STONE andAccessory:BA_NONE];

}

- (void)teardownGL
{
    [EAGLContext setCurrentContext:self.context];

    [testBlock tearDown];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.paused = !self.paused;
}

- (void)handleTapGesture:(UITapGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateRecognized) {

    }
}

#pragma mark - GLKView and GLKViewController delegate methods

- (void)update
{
    aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
    timeSinceLastUpdate = self.timeSinceLastUpdate;
    [testBlock update];
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    [testBlock draw];
}

@end

Defines.h:

#import <Foundation/Foundation.h>
#import <GLKit/GLKit.h>


enum BlockType {
    BT_NONE,
    BT_AIR,
    BT_GRASS,
    BT_DIRT,
    BT_STONE,
    BT_WATER,
    BT_SNOW,
    BT_WOOD,
    BT_LEAVES,
    BT_SAND,
    BT_GRAVEL
};

enum BlockAccessory {
    BA_NONE,
    BA_LADDER,
    BA_SNOW
};

enum Biome {
    BI_SNOWY,
    BI_PLAINS,
    BI_BEACH,
    BI_DESERT,
    BI_FOREST,
    BI_SAVANNA,
};

typedef enum BlockType BlockType;
typedef enum BlockAccessory BlockAccessory;
typedef enum Biome Biome;

typedef struct
{
    GLKVector3 positionCoordinates;
    GLKVector4 colorRGBA;
    GLKVector2 textCoord;
    GLKVector3 vertNorm;
} VertexData;

float aspect;
NSTimeInterval timeSinceLastUpdate;

VertexData vertices[] = {
    // Front
    {{1, -1, 1}, {1, 0, 0, 1}, {1, 0}, {0, 0, 1}},
    {{1, 1, 1}, {0, 1, 0, 1}, {1, 1}, {0, 0, 1}},
    {{-1, 1, 1}, {0, 0, 1, 1}, {0, 1}, {0, 0, 1}},
    {{-1, -1, 1}, {0, 0, 0, 1}, {0, 0}, {0, 0, 1}},
    // Back
    {{1, 1, -1}, {1, 0, 0, 1}, {0, 1}, {0, 0, -1}},
    {{-1, -1, -1}, {0, 1, 0, 1}, {1, 0}, {0, 0, -1}},
    {{1, -1, -1}, {0, 0, 1, 1}, {0, 0}, {0, 0, -1}},
    {{-1, 1, -1}, {0, 0, 0, 1}, {1, 1}, {0, 0, -1}},
    // Left
    {{-1, -1, 1}, {1, 0, 0, 1}, {1, 0}, {-1, 0, 0}},
    {{-1, 1, 1}, {0, 1, 0, 1}, {1, 1}, {-1, 0, 0}},
    {{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}, {-1, 0, 0}},
    {{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}, {-1, 0, 0}},
    // Right
    {{1, -1, -1}, {1, 0, 0, 1}, {1, 0}, {1, 0, 0}},
    {{1, 1, -1}, {0, 1, 0, 1}, {1, 1}, {1, 0, 0}},
    {{1, 1, 1}, {0, 0, 1, 1}, {0, 1}, {1, 0, 0}},
    {{1, -1, 1}, {0, 0, 0, 1}, {0, 0}, {1, 0, 0}},
    // Top
    {{1, 1, 1}, {1, 0, 0, 1}, {1, 0}, {0, 1, 0}},
    {{1, 1, -1}, {0, 1, 0, 1}, {1, 1}, {0, 1, 0}},
    {{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}, {0, 1, 0}},
    {{-1, 1, 1}, {0, 0, 0, 1}, {0, 0}, {0, 1, 0}},
    // Bottom
    {{1, -1, -1}, {1, 0, 0, 1}, {1, 0}, {0, -1, 0}},
    {{1, -1, 1}, {0, 1, 0, 1}, {1, 1}, {0, -1, 0}},
    {{-1, -1, 1}, {0, 0, 1, 1}, {0, 1}, {0, -1, 0}},
    {{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}, {0, -1, 0}}
};

GLubyte indices[] = {
    0, 1, 2,
    2, 3, 0,
    // Back
    4, 6, 5,
    4, 5, 7,
    // Left
    8, 9, 10,
    10, 11, 8,
    // Right
    12, 13, 14,
    14, 15, 12,
    // Top
    16, 17, 18,
    18, 19, 16,
    // Bottom
    20, 21, 22,
    22, 23, 20
};

Block.h:

#import <Foundation/Foundation.h>
#import "Defines.h"

@interface Block : NSObject
{

}

- (id)init;
- (id)initWithType:(BlockType)blockTypee andAccessory:(BlockAccessory)blockAccessorye;
- (void)setupEverythingElse;
- (void)setupVBOs;
- (void)draw;
- (void)update;
- (void)tearDown;

@end

Block.m:

#import "Block.h"

@interface Block ()
{
    BlockType blockType;
    BlockAccessory blockAccessory;
    GLuint _vertexBuffer;
    GLuint _indexBuffer;
    GLuint _vertexArray;
    float _rotation;
}

@property (strong, nonatomic) GLKBaseEffect *effect;

@end

@implementation Block

- (id)init
{
    self = [super init];
    if (self) {
        blockType = BT_NONE;
        blockAccessory = BA_NONE;
    }

    return self;
}

- (id)initWithType:(BlockType)blockTypee andAccessory:(BlockAccessory)blockAccessorye
{
    self = [super init];
    if (self) {
        blockType = blockTypee;
        blockAccessory = blockAccessorye;
    }

    return self;
}

- (void)dealloc
{
    [self tearDown];
}

- (void)tearDown
{
    glDeleteBuffers(1, &_vertexBuffer);
    glDeleteBuffers(1, &_indexBuffer);

    self.effect = nil;
}

- (void)setupEverythingElse
{
    glEnable(GL_CULL_FACE);

    self.effect = [[GLKBaseEffect alloc] init];
    self.effect.colorMaterialEnabled = NO;

    NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft: @YES};
    NSError *error;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
    GLKTextureInfo *info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
    if (info == nil)
        NSLog(@"Error loading file: %@", [error localizedDescription]);
    self.effect.texture2d0.name = info.name;
    self.effect.texture2d0.enabled = true;
    // Setup texture 2 if necessary (like a ladder on this block)

    [self setupVBOs];
}

- (void)setupVBOs
{
    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, positionCoordinates));
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, colorRGBA));
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, textCoord));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, vertNorm));

    glBindVertexArrayOES(0);
}

- (void)draw
{
    [self.effect prepareToDraw];
    glBindVertexArrayOES(_vertexArray);
    glDrawElements(GL_TRIANGLES, (sizeof(indices) / sizeof(indices[0])), GL_UNSIGNED_BYTE, 0);

    // Draw VertexData array
}

- (void)update
{
    // Setup texture 2 if necessary (like a ladder on this block)

    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 10.0f);
    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f);
    _rotation = 90 * timeSinceLastUpdate;
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(25), 1, 0, 0);
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 1, 0);
    self.effect.transform.modelviewMatrix = modelViewMatrix;
}

@end

抱歉这么长时间。感谢您阅读所有内容,或尽可能多地阅读。如果您需要更多详细信息,请告诉我。

2 个答案:

答案 0 :(得分:5)

您可能忘记添加所需的Frameworks

找到您需要导入和添加的框架,就像在屏幕截图

中一样

错过的框架可能会OpenGLES.framework尝试将其添加为下面的图片中

请参阅下面的图片Screenshot 1

ScreenShot 2

如果您对添加框架仍有任何疑问,请继续link

答案 1 :(得分:1)

您的“define.h”文件包含verticesindices的实际符号定义,而不仅仅是声明。任何在多个编译单元中导入/包含该文件的尝试都将导致重复的符号。

您需要将实际代码生成部分移动到实现文件而不是标题。