Re: [ROOT] error loading user library

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Fri Jun 29 2001 - 13:53:25 MEST


Hi Mike et al, 

On Thu, 28 Jun 2001 22:14:39 -0500 (CDT)
Mike Kordosky <kordosky@mail.hep.utexas.edu> wrote
concerning ": Re: [ROOT] error loading user library":
> 
> > This sound you forgot to provide an implementation of some virtual method of
> > your TestHeader class (destructor for example).
> > To reply your question one needs that class implementation file. 
> > That you did not send us yet.
> 
> Ok, I'm embarrassed :)
> Thanks!
> 
> By the way, is it typical for a compiler to let you get away with such
> actions?

Yes.  The point is, that you may have the implementation in another
file that is linked into another shared library.  In that case, you
need to load that library as well, _before_ loading the other
library.  On prime example in ROOT is libEGPythia.  If you try to load
that without loading libEG, then ROOT will fail. 

Some architectures does require that you have all references resolved
when you link your shared library (all architectures require all
symbols resolved when link a program); Digital Unix (normally)
requires that, but GNU/Linux doesn't.  There are ofcourse pros and
cons to eihter approach, and you can probably find lengthy discussions
on that on the web.   

On some architectures, I believe you can get the dynamic linker to
automatically load other libraries that you may need.  I believe this
is called incremental linking, but I may be wrong - someone please
correct me if I'm wrong.  What ever it is called, the above "strict"
architecttures usually does this loading for you, and in GNU/Linux I
believe you can make ld.so (the dynamic linker) automatically load
other libraries by explicitly linking your dynamic library agains it.  

I've attached a tar-ball with a small example that show this.  The
Makefile was written for a GNU/Linux system, so if you use something
else, it may not work.  Anyway, do 

  prompt% gzip -dc trylink-0.1.tar.gz | tar xvf - 
  prompt% cd trylink-0.1 
  prompt% make 
  
to build the stuff.  Then do:

  prompt% ldd ./baz
  	libBar.so => ./libBar.so (0x40015000)
	libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x4001e000)
	libm.so.6 => /lib/libm.so.6 (0x40060000)
	libc.so.6 => /lib/libc.so.6 (0x4007d000)
	libFoo.so => ./libFoo.so (0x40173000)
	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Notice that ld.so says that program "baz" needs to load library
libBar.so. Note, that the rest of the output differs from machine to
machine - mine was a Redhat 6.2.  libBar contains the class Bar
derived from class Foo, which however is in library libFoo.so.  So to
resolve all symbols, libFoo also need to be loaded at runtime.
However, it's not in the explicit list, so you'd think this may turn
ugly.  However, if we run the program: 

  prompt% ./baz 
  Hello from baz
  Foo:          1
  Bar:          0

the "Foo::Print" reference _is_ resolved - why? Well, libBar is linked
against libFoo, so ilibFoo will automatically be loaded when libBar
is. 

Yours, 

Christian  -----------------------------------------------------------
Holm Christensen                             Phone:  (+45) 35 35 96 91 
  Sankt Hansgade 23, 1. th.                  Office: (+45) 353  25 305 
  DK-2200 Copenhagen N                       Web:    www.nbi.dk/~cholm    
  Denmark                                    Email:       cholm@nbi.dk






This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:50 MET