I have been reading with a lot of interest this article: https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/
It has a specific section entitled 'Static library used by a shared library problems' which caught my attention. I've been experimenting a little bit beyond what the article describes, and there is something that I don't quite understand.
Using code snippets from the article, say I first create a trivial static library:
g++ util.cpp -o util.o -c -fPIC
ar r libutil.a util.o
Then I independently create a standalone object:
g++ code.cpp -o code.o -c -fPIC
At last, I create a shared library from the combination of both:
g++ code.o libutil.a -shared -o libcode.so
Now, as described in the article, if I look at the export table of the shared library, everything is as I expect:
$ nm -CD libcode.so | grep " T "
000000000000124c T _fini
0000000000001000 T _init
0000000000001167 T entry_point()
00000000000011d1 T util_function()
0000000000001145 T function1()
What I do not understand though, is that if I exclude code.o
from the shared library and only build it from the static archive:
g++ libutil.a -shared -o libcode.so
then in this case the export table of the shared library is totally empty:
$ nm -CD libcode.so | grep " T "
00000000000010f8 T _fini
0000000000001000 T _init
I figured out that in order to get the expected behaviour, I need to build the shared library as follows:
g++ -Wl,--whole-archive libutil.a -Wl,--no-whole-archive -shared -o libcode.so
In this case, symbols from the archive are exported as expected:
$ nm -CD libcode.so | grep " T "
00000000000011a0 T _fini
0000000000001000 T _init
0000000000001125 T util_function()
The way I look at it, static archives are simply a collection of standalone objects. However, when creating the shared library, it seems that static archives and standalone objects are treated slightly differently. Why is it necessary to use -Wl,--whole-archive
when the shared library is created from static archives without any standalone objects ?
Why is it necessary to use -Wl,--whole-archive when the shared library is created from static archives without any standalone objects ?
Because that's how archive libraries are designed to work -- their whole purpose it to provide needed objects, while leaving unneeded objects out of the link.