LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-09-2012, 07:26 AM   #1
miguelg
Member
 
Registered: Oct 2009
Location: UK
Distribution: Xubuntu
Posts: 31

Rep: Reputation: Disabled
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?

Last edited by miguelg; 12-09-2012 at 07:28 AM. Reason: Formatting
 
Old 12-10-2012, 04:25 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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++
 
Old 12-10-2012, 05:56 AM   #3
miguelg
Member
 
Registered: Oct 2009
Location: UK
Distribution: Xubuntu
Posts: 31

Original Poster
Rep: Reputation: Disabled
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?
 
Old 12-10-2012, 06:42 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Members of *.a archives are inserted only 'on-demand'.
 
Old 12-10-2012, 07:00 AM   #5
miguelg
Member
 
Registered: Oct 2009
Location: UK
Distribution: Xubuntu
Posts: 31

Original Poster
Rep: Reputation: Disabled
Thank you, NevemTeve.
 
Old 12-10-2012, 07:53 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by belnac View Post
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).

Last edited by johnsfine; 12-10-2012 at 08:01 AM.
 
Old 12-10-2012, 09:56 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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'
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How can we convert a dynamic library (filename.so) to a static library (filename.a). hanumaan Programming 4 11-20-2009 12:07 AM
LINUX - linking archive (static library) with shared (dynamic) library gurkama Programming 5 03-04-2007 11:11 PM
Linking a static library to a dynamic one delta4s Programming 2 09-28-2006 01:24 AM
static linking to c library lantern Programming 1 04-19-2004 08:58 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:36 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration