views:

70

answers:

2

Hello,

I've built a static library, to be linked in my iPhone apps. This library uses some global variables and functions, like in C. My problem is, when using for example:

extern
void do_stuff (const int a)
{
    return a*a;
}

extern const int a_variable;
extern const int an_array[DEFINED_VALUE];

When I use this function, or access these variables, anywhere in my code, the compiler tells me

"_do_stuff" referenced from: -[Object testMethod] in tests.o

"_a_variable" referenced from: -[Object testMethod] in tests.o

"_an_array" referenced from: -[Object testMethod] in tests.o

Symbol(s) not found Collect2: Id returned 1 exit status

Has anyone ever faced this problem before? I know I'm doing something stupid, I'm missing some key Objective-C or C concept, but I can't really see what. So I was hoping someone could help me. Thanks in advance.

+2  A: 

These are linker errors, telling you that the referenced entities can't be found. Probably this means that you haven't added your library to the project.

As an aside, you probably should distinguish between the place where you declare these things, where they should indeed be declared as extern, and the place where you define them, where they shouldn't be. That is, you might have a header file that includes:

extern void do_stuff (const int a);
extern const int a_variable;
extern const int an_array[];

And then an implementation file that has something like:

void do_stuff (const int a)
{
    return a*a;
}

const int a_variable = 42;
const int an_array[DEFINED_VALUE] = { 1, 2, 3, 4 };

As another aside, calling something a_variable when it's actually a const is a bit misleading!

walkytalky
I tried with the library linked to the target app, then tried with the target app depending on the library target. Both yield the same error. As for the declare/define point, I actually have the values and function bodies defined in a .mm file, I just gave an example for the sake of simplicity. Obviously the variables are not named a_variable, I just can't show any of my code due to a sigil contract.
Ricardo Ferreira
@Ricardo OK, that's a bit odd. Check that the library (`blah.a`) actually appears in the "Link Binary With Libraries" phase of your app target. Also check that the library actually exports the required symbols. If both those are true then I'm stumped...
walkytalky
@walkytalky Now that you mention it, perhaps it isn't exporting the symbols I want globally. But how can I be sure of that?
Ricardo Ferreira
@Ricardo Good question. Xcode may provide a friendly way to do this, but if so I don't know what it is. But you can run the command-line tool `nm` on your library file and look for the relevant symbols in the output. Your variables should probably have type `D` and your functions type `T`.
walkytalky
A: 

@walkytalky Well I ran nm on the .a filtered with grep to see if those symbols were exported.

host-006:Release-iphonesimulator <username>$ nm -g libCardLib.a | grep CP_
nm: no name list
     U _CP_BACK
     U _CP_FILE_EXTENSION_SUFFIX
     U _CP_FILE_PATH
     U _CP_SUIT_PREFIX
     U _CP_VALUE_PREFIX
00002020 D _CP_BACK
00002018 D _CP_FILE_EXTENSION_SUFFIX
0000201c D _CP_FILE_PATH
00002024 D _CP_FRONT
00002108 D _CP_SUIT_PREFIX
0000210c D _CP_VALUE_PREFIX
nm: no name list
nm: no name list
nm: no name list

So it seems that for each symbol there's an undefined copy?

Ricardo Ferreira
I wish I could pretend I knew what this means, but I don't. It seems like the .a file might contain multiple symbol tables -- maybe for different architectures? -- and the linker is looking for the symbols somewhere where they're undefined. But this is some way outside my area of knowledge, so don't listen to me. Hopefully someone who knows what they're talking about will be along soon!
walkytalky
ok, thanks for your help though :) If I can't solve this in a day or so, I'll simply resort to copying the headers and implementation files.
Ricardo Ferreira