5

I've built a static library that I'm my iOS binary is linking in. Code stripping is off, etc. for the static library, and I can see the symbols in the archive (via nm).

So, I link that library into my application as a framework. But, I'm not actually calling that function directly. As a result, I can see the symbols that I'm calling directly in my binary, but not the ones that aren't called. But, since I actually want these symbols to be there at runtime, I'm compiling with -all_load.

But, this seems to place an unnecessary burden on the users of the library. Is there something I can add in the static library that enforces this, rather than relying on the user of the library?

Masa
  • 520
  • 5
  • 13
  • Perhaps you could give an example of why you need the whole library loaded? There are ways to get the linker to do what you want (some of them quite easy) but there might be a more elegant solution to your issue. – Jim Hayes Mar 05 '14 at 03:40
  • I want to register components to handle certain types. My library has some standard components for some standard types. Clients can create more components for their specific types and register them. Each component just registers itself to handle a type. So, when it's "loaded" (via +load or __attribute__((constructor))), it registers itself. But, in a static library, since there's no code that explicitly calls the component, the component never actually registers itself. – Masa Mar 05 '14 at 08:43

1 Answers1

0

Depending on what you are trying to accomplish, you can precisely control which symbols are dead-stripped and which are always loaded, even if the user of the library doesn't actually use them.

The easiest way is to create a library initialization function that references the exact symbols you don't want dead-stripped. This is precise, and saves you the burden of wrestling with the linker command-line options, which may insulate you from (unlikely) tool behavior changes down the road.

Frameworks have automatic initializers (quite handy) that can be called automatically when the framework is loaded at runtime, right after any static variables are initialized.

__attribute__((constructor))
static void MyModuleInitializer()
{
    static BOOL initialized = NO;
    if (!initialized) {

        // References to symbols that should be kept around.

        initialized = YES;
    }
}

Just for grins, automatic finalizers are also supported using the __attribute__((destructor)) decorator.

Jim Hayes
  • 2,126
  • 1
  • 15
  • 21
  • But I don't want to have to have a global initialization that has to know about other parts of the library. If there has to be some central initialization, then there's not really a need to use __attribute__((constructor)) - just a function that calls into the symbols that I want to keep. – Masa Mar 05 '14 at 08:28
  • Perhaps I'm missing something here. :-) Are you saying that you want your _clients_ to create additional components as static libraries that just magically wake up and self-register with the components in _your_ static library at runtime? – Jim Hayes Mar 05 '14 at 22:45
  • Sure, they can create more components with the API in addition to the provided ones. – Masa Mar 06 '14 at 14:34
  • Then I don't see a way you're going to be able to get around having some supervisory code that glues everything together. You can always get at available symbols using the dyld library, `dlopen()`, `dlsym()`, etc. Other than that, I'm out of ideas. – Jim Hayes Mar 07 '14 at 04:45
  • Which is what I've always done, but this doesn't work on iOS app store apps. – Masa Mar 07 '14 at 23:04