Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply -fvisibility option to symbols in static libraries?

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.

like image 521
Steve Fallows Avatar asked Feb 08 '10 14:02

Steve Fallows


People also ask

Do static libraries have symbols?

At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.

How to use dynamic linking?

Dynamic linking is a two-step process that relies on accessing the addresses of code. The first step occurs at compilation. When a file is compiled with a dynamic library, instead of copying the actual object code contained in the library, the linker simply scans the code contained and checks for missing symbols.

What is difference between static linking and dynamic linking?

Definition. Static linking is the process of copying all library modules used in the program into the final executable image. In contrast, dynamic linking is the process of loading the external shared libraries into the program and then binds those shared libraries dynamically to the program.


2 Answers

Simply pass -Wl,--exclude-libs,ALL to gcc

This will tell the linker to transform all the symbols in the static libraries to hidden.

--exclude-libs also accepts a list of archives (i.e. static library names) for finer granularity on which libraries to hide symbols from.

Note: this will only work in systems using GNU binutils (e.g. Linux) or with a linker supporting --exclude-libs (e.g. it won't work with OSX's ld64)

like image 79
fons Avatar answered Oct 05 '22 23:10

fons


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
like image 31
F'x Avatar answered Oct 05 '22 23:10

F'x