views:

382

answers:

1

I have a shared library project that is built from 4 static libraries (.a) and one object (.o) file. I am trying to add the -fvisibility=hidden option to restrict symbols in the output to only those that I mark in the source with an _attribute_.

I've added the -fvisibility=hidden option to the compile options for the .so project (which covers the .o file) and for the .a projects.

The symbols in the object file are removed as expected from the final .so. However the symbols from the .a projects are all still in the final .so file. Adding the -fvisibility=hidden option to the .so link command has no effect.

What am I doing wrong?

My purpose here is to remove from the .so all symbols except the interface functions to the library.

EDIT: I actually used a version map to solve this for now. However it requires continued maintenance of the version script as external symbols change. Accepted answer has a better idea.

+4  A: 

Basically, visibility is handled during linking, and the linker doesn't seem impose it on static archives. A related question (though not a duplicate) was asked on SO here.

What I would advise you to do is to replace your linking stage: gcc -shared -o mylib.so foo.o libbar.a into a two stages process where you get back the object files:

  • ar x libbar.a (possibly into a suitable, empty directory)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
FX
Nice idea. Fits with what I learned by experimentation. May try this later.
Steve Fallows