Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC -rdynamic not working with static libraries

Why is -rdynamic not exporting the symbols in .a files but is exporting the symbols in .o files ?

I have an app and a plug-in in a .so file. The main app is linked using a series of object files and one static library, like this:

CXXFLAGS =      $(CXXFLAGS_COMMON) -rdynamic
STATICLIBS =    ../Utilities/Utilities.a
...

all:
    $(CXX) $(CXXFLAGS) -o $(SAMPLE) main.o $(STATICLIBS) $(SHAREDLIBS) $(INCLUDES)

(CXX is g++ 4.5.2 on Ubunut, I use mainly -std=c++Ox for compilation)

In this case, the symbols in Utilities.a are not exported (i.e. "objdump -t a.out | grep symbol" is empty).

If I use "ar x" to extract the .o files in the .a and link using only the .o's, then the symbols are exported and found by the plug-ins (that are loaded with dlopen in case you wondered).

I have tried using -Wl,-export-dynamic but without success.

I do have a workaround, as mentionned, but I'd still wish to understand what I am missing. Thanks in advance !

like image 336
J.N. Avatar asked Dec 22 '22 13:12

J.N.


2 Answers

Normally, the linker only includes those parts of static archives (.a files) which are referenced.

To force the linker to include the entire contents of a .a file, you can use the --whole-archive linker option (so -Wl,--whole-archive on the gcc command line).

Note that -Wl,--whole-archive is position-sensitive on the command line — it only affects .a files following it on the command line. Its effect may be subsequently turned off using -Wl,--no-whole-archive, if there are further static archives which you don't want to be completely included.

So, for instance, with your command:

$(CXX) $(CXXFLAGS) -o $(SAMPLE) main.o -Wl,--whole-archive $(STATICLIBS) -Wl,--no-whole-archive $(SHAREDLIBS) $(INCLUDES)
like image 86
snogglethorpe Avatar answered Dec 26 '22 10:12

snogglethorpe


A .o file is ELF relocatable, and, a .so file is ELF shared object. Whereas a .a file is current archive. When the linker is passed the --export-dynamic flag through the -rdynamic from gcc, it is looking for a dynamic object file.

I think the linker does not care to look into the archive and extract the symbols.

like image 22
vpit3833 Avatar answered Dec 26 '22 11:12

vpit3833