Weak extern function within a static iOS library?

114 views
Skip to first unread message

Michael Tyson

unread,
May 6, 2012, 3:19:40 PM5/6/12
to cocoa-...@googlegroups.com
Hi!

I'm creating a static audio engine library (call it Library A) that's intended for public consumption, but I want to include within it support for some features of another, separate library I'm building ("Library B", which influences the audio engine) that may or may not be present in the final compiled application.

I'm informed via a flag within the audio engine library that Library B is doing something (when, of course, Library B is present within the compiled app), whereupon I want to call a Library B function.

These are two separate projects, and I don't want to have either one rely on the other, but it would be beneficial for them to work together if they're both present within the final app.

I don't really have much experience with the finer points of compiling/linking, but it sounds to me like a weak symbol is what I'm after.

So, I tried to declare the function from Library B within the source code for Library A as a weak external function:

#define kAFlagIndicatingSomethingHappenedInLibraryB (1<<12)
extern void LibraryBFunction() __attribute__((weak));
...
if ( (flags & kAFlagIndicatingSomethingHappenedInLibraryB) && LibraryBFunction != NULL ) {
   LibraryBFunction();
}

This shows up as an undefined symbol in the compiled Library A, as expected:

$ nm libA.a
...
         U _LibraryBFunction

The problem is if I now link libA.a with an app missing Library B, I still get undefined symbol errors, missing LibraryBFunction.

I'm vaguely aware that there's some sequence of compiler/linker flags I can add (like -undefined dynamic_lookup, etc) to suppress these problems, but I'd really rather not require the end developer to add these flags to their build (plus it sounds like a bad idea for production code).

I'm also vaguely aware that there may be an attribute I can supply (weak_import, maybe?) that will cause the flagged method to not actually be linked in to the final binary, allowing a function to be overwritten during the link.  Is there perhaps a way I can use this to define a stand-in, stub LibraryBFunction within A that will allow an app without Library B to be compiled against Library A, without inducing undefined symbol errors, but still allow an app *with* Library B to be linked with Library A and have my Library A-Library B support functional?

Anything else I might have missed?

Many thanks in advance,
Michael


-- 
Michael Tyson | atastypixel.com

Live, app-to-app audio streaming is coming soon.
Don't want to miss our launch? Then sign up here: http://audiob.us



Michael Tyson

unread,
May 7, 2012, 6:33:30 AM5/7/12
to cocoa-...@googlegroups.com, Ji Fang
Hi again,

Just thought I'd update this: I've been experimenting with creating a stub in Library A for the function in Library B, and it seems to be working so far.

In Library A:

void LibraryBFunction();
__attribute__((weak)) void LibraryBFunction() {
    printf("Warning: LibraryBFunction stub called\n");
}

...
if ( (flags & kAFlagIndicatingSomethingHappenedInLibraryB) && LibraryBFunction != NULL ) {
   LibraryBFunction();
}

...And it links fine both with and without Library B present, and works properly with B when it is present (doesn't output the stub warning message, but calls the correct function).

I haven't yet determined if there are going to be link order issues, but I suspect it'll be okay, given the weak attribute seems to stop the stub being linked in at all, in the absence of Library B:

$ nm "Test App.app/Test App" | grep LibraryBFunction
(nothing)

Oddly enough, LibraryBFunction still has a non-NULL value when linked without Library B, and can even be called (and prints out the stub warning message), even though it doesn't appear in the listing from nm. In fact, doing a diff between the nm output with and without the stub shows no changes at all.

But anyway, it seems to work.


On 7 May 2012, at 01:03, Ji Fang wrote:

Weak symbol in linking only applies to dynamic library. Since iOS app are statically linked, there isn't much luck of using the weak symbol here. 


Sent from my iPhone

Reply all
Reply to author
Forward
0 new messages