views:

151

answers:

3

Suppose I have a static library libx.a. How to I make some symbols (not all) from this library to be always present in any binary I link with my library? Reason is that I need these symbols to be available via dlopen+dlsym. I'm aware of --whole-archive linker switch, but it forces all object files from library archive to linked into resulting binary, and that is not what I want...

Observations so far (CentOS 5.4, 32bit) (upd: this paragraph is wrong; I could not reproduce this behaviour)

ld main.o libx.a

will happily strip all non-referenced symbols, while

ld main.o -L. -lx

will link whole library in. I guess this depends on version of binutils used, however, and newer linkers will be able to cherry-pick individual objects from a static library.

Another question is how can I achieve the same effect under Windows?

Thanks in advance. Any hints will be greatly appreciated.

A: 

I would start with splitting off those symbols you always need into a seperate library, retaining only the optional ones in libx.a.

DevSolar
+1  A: 

Take an address of the symbol you need to include.

If gcc's optimiser anyway eliminates it, do something with this address - should be enough.

qrdl
Thanks, but I already thought of this hack; I'm wondering if there are clean ways to do it.
kolbusa
@kolbusa Hacks don't harm :)
qrdl
@kolubsa: I wouldn't consider this a hack ... you need to reference the symbols in some way to make the linker pull them in.
Nicholaz
@qrld Yes, but this way I will have to make symbols visible in some places where they are currently not (they are just sitting in separate object file...).
kolbusa
@kolbusa I didn't get it. If these symbols are not visible, `dlsym()` don't find them, so they have to be visible.
qrdl
@qrld I mean that I need to put these address manipulations into a function that is a) publically visible and b) is always called. I do have such a function, but what I meant is that from code modularity point of view, putting such code there does not make much sense...
kolbusa
+2  A: 

First things first: ld main.o libx.a does not build a valid executable. In general, you should never use ld to link anything directly; always use proper compiler driver (gcc in this case) instead.

Also, "ld main.o libx.a" and "ld main.o -L. -lx" should be exactly equivalent. I am very doubtful you actually got different results from these two commands.

Now to answer your question: if you want foo, bar and baz to be exported from your a.out, do this:

gcc -Wl,-u,foo,-u,bar,-u,baz main.o -L. -lx -rdynamic

Update:
your statement: "symbols I want to include are used by library internally only" doesn't make much sense: if the symbols are internal to the library, why do you want to export them? And if something else uses them (via dlsym), then they are not internal to the library -- they are part of the library public API.

You should clarify your question and explain what you really are trying to achieve. Providing sample code will not hurt either.

Employed Russian
1. indeed, I cannot reproduce difference between -l and specifying library directly now. Maybe I did something wrong that time...2. While -u looks like a solution, to use it I need to know list of "extra" symbols when building a binary. I would like to "hide" these dependencies (symbols I want to include are used by library internally only).
kolbusa