MK. February 2016

simulating --whole-archive behavior on per symbol basis

I am familiar with what the --whole-archive linker option does when using a static archive.

Is there a way to achieve the same effect on a per symbol basis, either via some symbol attributes, or any other trick?

To be clear, lets say I have a .a which has two functions :

void foo() {}
void bar() {}

I would like to make sure that any executable that was built by linking against this archive will always have the foo() symbol, regardless of whether foo() is being used or not. I do not similarly care about bar()

Thanks.

Answers


Ctx February 2016

You can use the option -u for that:

gcc -O2 foo.c -o foo -umysymbol -lmylib

This forces the linker to treat mysymbol as undefined and resolve it by linking it from the specified libraries.

From the manpage of ld:

-u symbol

--undefined=symbol

Force symbol to be entered in the output file as an undefined symbol. Doing this may, for example, trigger linking of additional modules from standard libraries. `-u' may be repeated with different option arguments to enter additional undefined symbols.


Mike Kinghan February 2016

I'm afraid you'll need to modify your linkage to achieve this.

You should be clear that the entities within an archive (.a) that can be linked, or not linked, with your executable are not individual symbol definitions but individual archive members, which are object files, each of which may define arbitrarily many symbols. If you want to link a symbol from an archive, you link the whole archive member that defines it.1

The foremost difference between linking an archive (.a) with your executable and linking an object file (.o) is that an object file will be linked, unconditionally, whereas an archive member will be linked only if it provides a definition for at least one symbol that has been referenced but not defined when the archive is examined.

Hence the ordinary, non-roundabout way of ensuring that a symbol foo is linked unconditionally is to link an object file that defines it. There is no way to mark an archive member foo.o as must be linked because, if you must link foo.o, you do it by linking foo.o.

So if foo resides in an archive member foo.o, you can extract that member from the archive:

ar x libthing.a foo.o

and add foo.o to your linkage, even if you don't have the foo source from which to compile foo.o.

If there are a lot of functions that you want to link unconditionally then you might either compile them all from source into a single object file, if you have the source, or you might collect all the object files that define them into a single archive that you link with --whole-archive.

I was hoping to find a way to advertise the public nature of the symbol in the library itself

For linkage purposes, t


MK. February 2016

The following seems to have worked for me.

In a function in my library that I know is always called, I do the following :

static volatile auto var = &foo

Now, without changing anything in the linking either when creating the archive or building the executable, I see that the executable has the foo symbol.

Post Status

Asked in February 2016
Viewed 1,295 times
Voted 10
Answered 3 times

Search




Leave an answer