LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Linking static library INTO dynamic library (https://www.linuxquestions.org/questions/programming-9/linking-static-library-into-dynamic-library-4175440660/)

miguelg 12-09-2012 07:26 AM

Linking static library INTO dynamic library
 
When loading an so with dlopen I'm getting an undefined symbol which I can't resolve.

The so is being created like so:

g++ -shared -pthread -lboost_system -lboost_thread -lboost_filesystem -L/usr/local/lib -ldl -lpthread -lstdc++ -fPIC -ldl ../../src/libbar.a -o libfoo.so *.o

Note above the ../../src/libbar.a which (as I understand it) should link the .a into the resulting so.

But when I run the executable that loads the so it aborts with an undefined symbol error:

libfoo.so: undefined symbol: _ZN10OmnisourceD2Ev

The offending symbol (a C++ class) is indeed in libbar.a as nm shows:

$ nm out/src/libbar.a|grep -i Omnisource
omnisource.o:
0000000000000000 T _ZN10OmnisourceC1EPvSs
0000000000000000 T _ZN10OmnisourceC2EPvSs
0000000000000100 T _ZN10OmnisourceD1Ev
0000000000000100 T _ZN10OmnisourceD2Ev
U _ZN16OmnisourceLoader4loadERKSs
0000000000000000 W _ZN5boost10shared_ptrI10OmnisourceED1Ev
0000000000000000 W _ZN5boost10shared_ptrI10OmnisourceED2Ev

What am I doing wrong here?

NevemTeve 12-10-2012 04:25 AM

You might try to change the order:

Code:

g++ -shared -pthread -fPIC -L/usr/local/lib -o libfoo.so *.o ../../src/libbar.a -lboost_system -lboost_thread -lboost_filesystem -ldl -lpthread -lstdc++

miguelg 12-10-2012 05:56 AM

Found the solution here: http://entrenchant.blogspot.co.uk/20...to-shared.html

Turns out one has to use the following syntax:

gcc -shared -o libfoo.so -Wl,-whole-archive ../../src/libbar.a -Wl,-no-whole-archive

Why though?

NevemTeve 12-10-2012 06:42 AM

Members of *.a archives are inserted only 'on-demand'.

miguelg 12-10-2012 07:00 AM

Thank you, NevemTeve.

johnsfine 12-10-2012 07:53 AM

Quote:

Originally Posted by belnac (Post 4846143)
Turns out one has to use the following syntax

I understand why that eliminated your symptom, but I don't believe it was either necessary or best.

You should try NevemTeve's earlier suggestion: Move the .a file in the linker command line so that it appears after all the .o files.

Linker documentation won't tell you the simple rule that .a files must be later in the command line than .o files, because the linker does not consider that to be an absolute rule. I'm sure there is some obscure situation in which you would want some .a file before some .o file in a linker command (though at the moment I can't think of it). But the relative sequence often makes a difference and when it does make a difference the results you get by putting the .a after the .o are almost certainly what you want and the results of putting the .a before the .o are likely not what you want (as in this case where a symbol gets resolved at link time if the .a is after the .o, but is left to be resolved at load time if the .a is before the .o).

NevemTeve 12-10-2012 09:56 AM

Other problems may arise, for example if libbar.a contains position-dependent code. I'd suggest using libtool: libbar.a (or libbar.la) would be a 'convenience library'


All times are GMT -5. The time now is 04:38 PM.