51

Under gcc (g++), I have compiled a static .a (call it some_static_lib.a) library. I want to link (is that the right phrase?) this .a file into another dynamic library (call it libsomeDyn.so) that I'm building. Though the .so compiles, I don't see content of .a under .so using nm command:

/usr/bin/g++ -fPIC -g -O2 -Wall -Werror -pipe -march=pentium3 -mtune=prescott -MD -D_FILE_OFFSET_BITS=64 -DLINUX -D_GNU_SOURCE -D_THREAD_SAFE -I../../../../../../../../ -I../../../../../../../..//libraries -Wl,-rpath,/usr/lib -o libsomeDyn.so some.o another.o some_static_lib.a -shared -Wl -x -Wl,-soname,libsomeDyn.so

I do not see functions under some_static_lib.a under libsomeDyn.so. What am I doing wrong?

bob
  • 1,941
  • 6
  • 26
  • 36

2 Answers2

64

Static libraries have special rules when it comes to linking. An object from the static library will only be added to the binary if the object provides an unresolved symbol.

On Linux, you can change that behavior with the --whole-archive linker option:

g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • 1
    So I have some weird dependency in the static library. It references a function included in the dynamic library. How do I tell gcc to find the undefined reference inside the dynamic library? Thanks – bob Apr 16 '10 at 00:26
  • 1
    @bob - there should be no problem with the static library referencing a symbol within the dynamic library (once you link a static library, it's just the same as if you directly referenced the .o on the command line). I suspect there must be some other problem and recommend posting a new question. – R Samuel Klatchko Apr 16 '10 at 04:15
  • 3
    It was the solution for me, but on OSX I had to use `-all_load` as an equivalent to `--whole-archive` as someone suggested me on IRC. I hope it could help someone else! – vmonteco Jun 11 '17 at 14:16
25

For every one that comes across that problem like me (and has not understand the answer properly): here is a short howto generate a dynamic library (libmylib.so) from a static one (mylib.a):

1.) create a mylib.c file that only imports the mylib.h file

2.) compile this mylib.c to mylib.o with

gcc -c -fPIC mylib.c -o mylib.o

3.) generate a dynamic library with the following command:

gcc --whole-archive -shared -Wl,-soname,libmylib.so -o libmylib.so mylib.o mylib.a 

That worked at least for me, turning a static library (compiled with -fPIC) to a dynamic library. I'm not sure wether this will work for other libraries too.

Riccardo T.
  • 8,907
  • 5
  • 38
  • 78
  • 3
    is step 2 supposed to say "mylib.o" instead of "msat.o"? – mwag May 25 '16 at 16:39
  • 2
    I have not tested it, but the basic idea is likely OK. Technically, --whole-archive is a linker option (gcc will not understand it if you pass it as "gcc --whole-archive"). Instead it should be moved past "-Wl", for example: gcc -shared -Wl,--whole-archive,-soname,libmylib.so ... I would edit the answer, but I have no way to test if it works. In the current form, it will lead to a gcc error ("unrecognized command line option ‘--whole-archive’"). – Philipp Claßen Jul 27 '17 at 22:56
  • 1
    Also the -Wl,--whole-archive ... -Wl,--no-whole-archive block should be around the static library (mylib.a). Like in the accepted answer. – Philipp Claßen Jul 27 '17 at 23:05
  • I noticed that you forgot to write the step to produce `mylib.a`. Why don't you use different name for the static library, for example `mystaticlib.a`? – Second Person Shooter May 09 '21 at 14:21