0

I am getting this error for a single class from a static library, which I have compiled myself. It has all been working fine and I wanted to add another class as a simple data transfer object called PPClientData. The error is:

Undefined symbols for architecture armv7: "_OBJC_CLASS_$_PPClientData", reference from: objc-class-ref in CPPIntegrationDelegate.o

The relevant file is included in the library compile targets and I have used otool -d on the (fat) library and it shows

libPPIntegration.a(PPClientData.o) (architecture armv7): (__DATA,--data) section

The header for the class (PPClientData.h), which is included in the app is like this:

#import <Foundation/Foundation.h>

@interface PPClientData : NSObject
    @property(nonatomic, strong) NSString* clientId;
    // 3 others identical to the above with different names
@end

and the .m file which should be compiled into the library looks like this:

#import "PPClientData.h"

@implementation PPClientData
@synthesize clientId;
//Synthesize others

-(id)init {
    self = [super init];
    return self;
}
@end

It is consumed in a single class in the app as follows. If this one function that consumes it is commented out, the linker error goes away (it links to other classes in the library) but with this in, it fails. This is a delegate function for the library.

#import "CPPIntegrationDelegate.h"
#import "PPClientData.h"

@implementation CPPIntegrationDelegate

// Various other functions that work fine

-(PPClientData*)clientData:(PPIntegration*)integration {
    PPClientData* dict = [[PPClientData alloc]init];      // This is the line that causes the linker error
    dict.clientId = @"whatever";
    // set other properties of dict
    return dict;
}

I understand what the linker is trying to do and what the error suggests but I don't see what I've missed. Can anyone help?

Lukos
  • 1,826
  • 1
  • 15
  • 29
  • Is the static library produced by an Xcode subproject embedded in the main project? – bgfriend0 Apr 11 '14 at 15:27
  • It is produced in an xcode project but it is not embedded in the main project. – Lukos Apr 11 '14 at 15:28
  • Hmm, not sure then. There are issues if you embed a 64-bit project inside a 32-bit project and try to build to a 64-bit device. Even though the 64-bit project supports 32-bit, if "build active architecture only" is enabled (which it usually is for debug), the subproject will not check with the parent project and you'll get issues of the sort you describe. There must be something else going on. – bgfriend0 Apr 11 '14 at 15:32
  • The only other thing that has changed is that I have just updated XCode to the latest version (just a minor increase) I might check that out. – Lukos Apr 11 '14 at 15:36
  • The latest version of Xcode does change the 64 bit architecture defaults. I just updated and had to change a lot of c++ code to allow for pointer to int conversion losing precision. I'm willing to bet that is your problem. – Putz1103 Apr 11 '14 at 15:45
  • I had the same experience as @Putz1103. – RobP Apr 11 '14 at 18:32

2 Answers2

0

If you are on Xcode 5.1, try to remove arm64 from Valid Architectures (under Build Settings) and also change the Architectures from "Standard architectures" to just armv7 and armv7s. This might be relevant to you: how to stop xcode5.1 building for 64bit

Community
  • 1
  • 1
tll
  • 377
  • 1
  • 3
  • 12
  • well, that's one approach. Fixing all your types to be portable and actually making arm64 *work* seems preferable, but yes it can be time-consuming. – RobP Apr 11 '14 at 18:33
  • Yes I agree it's preferable. Whether it's best to do so depends on the priority and complexity of the static library. – tll Apr 11 '14 at 18:42
  • I don't understand how this relates to the linker problem. Firstly, the class that causes the problems only uses NSString and secondly, if I remove/comment out that class, the rest of the library links fine. Thirdly, the symbols it can't link are not the 64 bit version. I might try it though to rule it out. – Lukos Apr 14 '14 at 14:52
0

Well, it wasn't the architectures causing the problem but in some way, xcode or whatever had been confused by the order of the forward declaration of the class I was using and then the definition itself. Initially, the broken code was something like:

BrokenClass.h

// Definitions etc.

GoodClass.h

@class BrokenClass;
- (BrokenClass*)someMethod:(SomeType*) param;

GoodClass.m

#import "BrokenClass.h"

- (BrokenClass*)someMethod:(SomeType*) param
{

}

Which was included into my App by including GoodClass.h into a header file, which forward declared BrokenClass and then included BrokenClass.h into an m file which should have completed the definition, where the class was used.

Anyway, to fix it, I changed the GoodClass code to:

GoodClass.h

#import "BrokenClass.h"
- (BrokenClass*)someMethod:(SomeType*) param;

Removed the #import in the m file and then only included the one GoodClass.h into my app (which brought in the BrokenClass).

Whether this is a bug somehow or more likely, I had too many forward declarations etc. I'm not sure.

Lukos
  • 1,826
  • 1
  • 15
  • 29