Some platforms mandate that you provide a list of a shared library's external symbols to the linker. However, on most unixish systems that's not necessary: all non-static symbols will be available by default.
My understanding is that the GNU toolchain can optionally restrict visibility just to symbols explicitly declared. How can that be achieved using GNU ld?
GNU
ld
can do that on ELF platforms.Here is how to do it with a linker version script:
By default, all symbols are exported:
Let's say you want to export only
bar()
andbaz()
. Create a "version script"libfoo.version
:Pass it to the linker:
Observe exported symbols:
The code generated to call any exported functions or use any exported globals is less efficient than those that aren't exported. There is an extra level of indirection involved. This applies to any function that might be exported at compile time. gcc will still produce extra indirection for a function that is later un-exported by a linker script. So using the visibility attribute will produce better code than the linker script.
I think the easiest way of doing that is adding the
-fvisibility=hidden
to gcc options and explicitly make visibility of some symbols public in the code (by__attribute__((visibility("default")))
). See the documentation here.There may be a way to accomplish that by ld linker scripts, but I don't know much about it.
If you are using libtool, there is another option much like Employed Russian's answer.
Using his example, it would be something like:
Then run libtool with the following option:
Note that when using -export-symbols all symbols are NOT exported by default, and only those in export.sym are exported (so the "local: *" line in libfoo.version is actually implicit in this approach).