54

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?

2 Answers 2

69

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
Sign up to request clarification or add additional context in comments.

3 Comments

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 - 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.
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!
24

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.

5 Comments

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’").
Also the -Wl,--whole-archive ... -Wl,--no-whole-archive block should be around the static library (mylib.a). Like in the accepted answer.
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?
Something is wrong with this. Step 2 just compiles mylib.c to mylib.o. This is not a static library. You need a step "2.5" to generate a static library mylib.a from mylib.o. In step 3 you are linking the mylib.o and the mylib.a. You should just link the mylib.a.
@StevenDickinson you misunderstand, he already has the static library, he is just making a hack, a dynamic wrapper of the static library, quite genious.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.