views:

862

answers:

3

I have a Library X that depends on Library Y. I have an App A that calls functions from X.

Assume that Library Y is only available as a static library. If both X and Y are statically linked to App A, everything works fine. However, I want X to be a dynamic (shared) library.

Currently, having A link Y statically doesn't work as the dynamic X can't see what's in Y.

Is there any way to get Y as a dynamic library without having to statically link X to Y? It's not OK for us to wrap Y so that we have a dynamic version of Y. Generally speaking, are there linker options available that somehow expose Y (which is statically linked to A) to X (dynamic library)?

Reason I'm asking is that I also have Library Z that also depends on Y. I don't want to have to statically link Y into both X and Z just so X and Z can be dynamic.

Hope this isn't too confusing. I appreciate any help.

+1  A: 

Well, it's fairly simple to convert a static library into a .so:

gcc -shared library.a -oliblibrary.so

Does that solve it?

dicroce
Thanks for the reply.Unfortunately, I'm not allowed to touch the static library... it must remain a static library. Just wondering if it was possible somehow to expose the static library (linked to the app) to the dynamic ones.
WY
A dynamic library's symbols are resolved at load time... So, dynamically loaded library's with undefined references should be able to resolve those dependencies against your app. If this works, let me know and I'll create another answer.
dicroce
A: 

As you point out - If you wrapped Y or had a dynamic Y your problems would be solved.

Why can't you wrap Y to make it dynamic?

Why can't you get a dynamic Y?

Given your intransigent constraints you might have to link Y for Z and X. You are basically removing all your options...

Tim
+2  A: 

You want to compile a dynamic version of X that statically links Y. Then the application only links X, and is oblivious to the use of Y. Whether or not you can do that varies by platform I think -- I know GCC and the GNU linker will allow it. The issue is that code compiled for use as a static library and code compiled for use as a dynamic library is not identical; dynamic libraries are generated such that they can be relocated in any area of memory (this makes them shareable). On Linux and Solaris, this means that shared libraries are compiled with the "-fpic" directive. If you mix PIC'd and non-PIC'd code when you make your shared library (this is what happens when you statically link Y to X), you'll get errors about unresolved text relocations -- that's the linker complaining that parts of your library are unsharable. You can disable the warnings by passing -mimpure-text. However, realize that any page in memory that contains code that wasn't compiled with "-fpic" (so any page that contains a call to Y) will not be shared across apps. So if multiple apps are using your library, they won't get the full memory savings usually bestowed by using shared libraries. There are probably equivalent flags on Windows for MSVC if that's your platform.

Edit: On my first read didn't catch your problem with Z. Try compiling X and Z with "-z undefs" so that GCC will ignore undefined symbols, then when you link your app make sure Y is on the link line after X and Z (later libraries fill in references found in earlier libraries).

Joseph Garvin