Root Talk Forum Index Root Talk
ROOT Discussion Forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Private shared library do not load in ROOT v5.15.04
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Root Talk Forum Index -> ROOT Support
View previous topic :: View next topic  
Author Message
pad



Joined: 15 Apr 2005
Posts: 39

PostPosted: Sat Apr 14, 2007 20:29    Post subject: Private shared library do not load in ROOT v5.15.04 Reply with quote

Hello,

This is certainly a known feature, but loading private shared library changed between 5.12 and 5.15 (didn't try 5.14)

I'm compiling my shared library with a rootcint-gnerated dictionnary.
Then in 5.12 I could do :

Code:
root -l
root [0] .L libs/libJetCore.so
root [1]


With 5.15 I have :
Code:
root -l
root [0] .L libs/libJetCore.so
dlopen error: /home/delsart/stuff/new/./libs/libJetCore.so: undefined symbol: _ZN5TFileC1EPKcS1_S1_i
Load Error: Failed to load Dynamic link library /home/delsart/stuff/new/./libs/libJetCore.so
*** Interpreter error recovered ***
root [1]


I now need to do gSystem->Load("libTree.so") before loading my lib.

Is there a way to compile my lib so that ROOT automatically loads what is need when I try to load it ?

Thanks for your help,

P.A.
Back to top
View user's profile Send private message
musinsky



Joined: 07 Feb 2005
Posts: 161
Location: UPJS Kosice, Slovakia

PostPosted: Sun Apr 15, 2007 10:23    Post subject: Reply with quote

Maybe help ROOT utility rlibmap ? (man rlibmap)
    rlibmap -f -r .rootmap -l pathToLib/libJetCore.so -d libTree -c pathToInclude/LinkDef.h
Now, you dont need .L libs/libJetCore.so, nor libTree.so
Code:
root [0] jet = new JetCore()
Jan
Back to top
View user's profile Send private message Send e-mail
Axel



Joined: 03 Sep 2003
Posts: 1506
Location: CERN

PostPosted: Sun Apr 15, 2007 12:36    Post subject: Reply with quote

Hi,
with current CVS the recommended rootmap name for libName.so is libName.rootmap, i.e.
Code:
rlibmap -f -o pathToLib/libJetCore.rootmap -l pathToLib/libJetCore.so -d libTree -c pathToInclude/LinkDef.h
Makes it a bit more modular. If you have LD_LIBRARY_PATH set to include pathToLib root will be able to load libJetCore when you access the JetCore class.
Axel.
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Fri May 11, 2007 9:02    Post subject: Reply with quote

Hi rooters,
I have a similar problem: I have private shared library with many classes + dictionaries that I was used to load with

.L /directory/mylibrary.so
(if you need the compilation details just ask)

and now, with root 5.15, it doesn't work anymore, since it complains for missing symbols (that are present in some of the ROOT libs).
How can I fix the problem? do you have a usage example for rlibmap?

Regards
Luigi
Back to top
View user's profile Send private message
Axel



Joined: 03 Sep 2003
Posts: 1506
Location: CERN

PostPosted: Fri May 11, 2007 10:26    Post subject: Reply with quote

Hi,

you might need to load a ROOT lib before loading your lib. Alternatively, as you said, you can run rlibmap. See my example of how to call it in me previous posting. Don't forget to set LD_LIBRARY_PATH so it also includes the directory that your library is in - otherwise ROOT cannot find the rootmap file.

Axel.
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Fri May 11, 2007 11:52    Post subject: Reply with quote

Hi Axel,
I have the following questions:
1) should I manually guess which are the needed ROOT libraries (-d option of rlibmap)? by trial and error? Shocked
2) if I run:
rlibmap -f -o mylib.rootmap -l mylib.so -d DUMMY -c mylibLinkDef.h
it produces
Library.mylib: mylib.so DUMMY
so rlibmap does not check whether DUMMY is a real library or not. is it correct?
3) what is the meaning of the " -f "option of rlibmap?

BTW, I don't need the "automatic load" feature, but only a working
.L mylib.so Very Happy

Regards
Luigi
Back to top
View user's profile Send private message
Axel



Joined: 03 Sep 2003
Posts: 1506
Location: CERN

PostPosted: Fri May 11, 2007 17:36    Post subject: Reply with quote

Hi Luigi,
luigi wrote:
1) should I manually guess which are the needed ROOT libraries (-d option of rlibmap)? by trial and error? :shock:

You can check by looking at the output of
Code:
symbols=`nm -C mylib.so | grep -E ' U T[[:alnum:]_]+::' | sed 's,^.* U \([[:alnum:]_]\+\)::.*$,(\1),'| sort | uniq | tr '\n' '|'`; (for so in $ROOTSYS/lib/*.so; do nm -C -D --defined-only $so | grep -E 'T ('$symbols')::' > /dev/null && echo $so; done )| sort | uniq


luigi wrote:
2) if I run:
rlibmap -f -o mylib.rootmap -l mylib.so -d DUMMY -c mylibLinkDef.h
it produces
Library.mylib: mylib.so DUMMY
so rlibmap does not check whether DUMMY is a real library or not. is it correct?

Yes, we trust you :-)

luigi wrote:
3) what is the meaning of the " -f "option of rlibmap?

From $ROOTSYS/utils/src/rlibmap.cxx
Quote:
// This program generates a map between class name and shared library.
// Its output is in TEnv format.
// Usage: rlibmap [-f] [-o <mapfile>] -l <sofile> -d <depsofiles>
// -c <linkdeffiles>
// -f: output full library path name (not needed when ROOT library
// search path is used)
// -o: write output to specified file, otherwise to stdout
// -r: replace existing entries in the specified file
// -l: library containing the classes in the specified linkdef files
// -d: libraries on which the -l library depends
// -c: linkdef files containing the list of classes defined in the -l library


luigi wrote:
BTW, I don't need the "automatic load" feature, but only a working
.L mylib.so :D

Either load the dependent libs before, or create a rootmap file.

Axel.
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Fri May 11, 2007 18:21    Post subject: Reply with quote

Dear Axel,
thank you for the reply and for the (black) magic Cool
Anyway I am still not able to load my library.....

I have reduced the problem to the following minimal class that uses root:

Code:

// myclass.h
#include <TObject.h>
#include <TH1.h>


class myclass: public TObject{
 public:
  myclass(int a, int b);

  ClassDef(myclass,2);
};


Code:

// myclass.cxx
#include <myclass.h>

ClassImp(myclass);

myclass::myclass(int a, int b)
{
  printf("useless ctor %d %d\n",a,b);
  TH1F *h=new TH1F("h1","h1",100,a,b);
  h->Draw();
}


Code:

//myclassLinkDef.h
#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class myclass+;
#endif


that I compile (under Linux gcc version 4.1.2 Debian 4.1.1-21) with:

Code:

rm *Dict* *.o

$ROOTSYS/bin/rootcint myclassDict.cxx -c -p myclass.h myclassLinkDef.h

g++ -c -I. -I$ROOTSYS/include myclass.cxx -o myclass.o
g++ -c -I. -I$ROOTSYS/include myclassDict.cxx -o myclassDict.o

g++ -shared myclass.o myclassDict.o -o myclass.so


.L myclass.so works nicely in root 5.13.04, but I have problems in root 5.15:

Code:

root
.L myclass.so
dlopen error: ./myclass.so: undefined symbol: _ZN4TH1FC1EPKcS1_idd


your script says:

/usr/local/root_v5.15/lib/libCore.so
/usr/local/root_v5.15/lib/libHist.so

so I type:
Code:

root
.L /usr/local/root_v5.15/lib/libCore.so
.L /usr/local/root_v5.15/lib/libHist.so
dlopen error: /usr/local/root_v5.15/lib/libHist.so: undefined symbol: _ZN8TVectorTIdE4DrawEPKc


if I use a myclass.rootmap like
Code:

Library.myclass:                            myclass.so libCore
Library.myclass:                            myclass.so libHist


it says:
Code:

.L myclass.so
Note: File "/usr/local/root_v5.15/lib/libCore.so" already loaded
Note: File "/usr/local/root_v5.15/lib/libCore.so" already loaded
Note: File "/usr/local/root_v5.15/lib/libCore.so" already loaded
Error in <TCint::AutoLoad>: failure loading library myclass.so for class myclass
dlopen error: /home/bardelli/rootfiles/classi515/./myclass.so: undefined symbol: _ZN4TH1FC1EPKcS1_idd
Load Error: Failed to load Dynamic link library /home/bardelli/rootfiles/classi515/./myclass.so
Error in <TCint::AutoLoad>: failure loading library myclass.so for class myclass

and an infinite loop starts........

Any help is appreciated (and sorry for the giant post Rolling Eyes )
Luigi
Back to top
View user's profile Send private message
pcanal



Joined: 27 Aug 2003
Posts: 3586
Location: Fermilab

PostPosted: Sat May 12, 2007 6:52    Post subject: Reply with quote

Hi,

Keep only the line:
Code:
Library.myclass:                            myclass.so libHist

Cheers,
Philippe.
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Mon May 14, 2007 10:42    Post subject: Reply with quote

Dear Philippe,
that does not seem to work....:
Code:

root [0] .L myclass.so 
Note: File "/usr/local/root_v5.15/lib/libHist.so" already loaded
Note: File "/usr/local/root_v5.15/lib/libHist.so" already loaded
Note: File "/usr/local/root_v5.15/lib/libHist.so" already loaded
Note: File "/usr/local/root_v5.15/lib/libHist.so" already loaded
....

infinite loop again...... Sad

Luigi
Back to top
View user's profile Send private message
pcanal



Joined: 27 Aug 2003
Posts: 3586
Location: Fermilab

PostPosted: Mon May 14, 2007 21:00    Post subject: Reply with quote

What about
Code:
Library.myclass:                            myclass.so libHist.so
?
Philippe
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Tue May 15, 2007 8:50    Post subject: Reply with quote

Hi Philippe,
here are the results:
Code:

root
 .L myclass.so
Error: cannot open file "/home/bardelli/rootfiles/classi515/./myclass.so"  myclass.so:1:
Error in <TCint::AutoLoad>: failure loading library myclass.so for class myclass
Error in <TCint::AutoLoad>: failure loading library myclass.so for class myclass
Error in <TCint::AutoLoad>: failure loading library myclass.so for class myclass

and, again, infinite loop...

BTW, are you able to reproduce my problems?
Regards
Luigi
Back to top
View user's profile Send private message
pcanal



Joined: 27 Aug 2003
Posts: 3586
Location: Fermilab

PostPosted: Tue May 15, 2007 22:53    Post subject: Reply with quote

Hi,

Yes I can reproduce your problem. The 'issue' comes from the fact that you library and class have the same name. As a work around you should name your library libclass.so.

Cheers,
Philippe
Back to top
View user's profile Send private message Send e-mail
luigi



Joined: 04 Sep 2003
Posts: 32
Location: Florence, Italy

PostPosted: Wed May 16, 2007 11:08    Post subject: Reply with quote

Dear all,
now it works.... I summarize here my findings, just in case someone is interested:

ROOT pre 5.15
if you have some classes Class1 Class2 etc in a file mylib.so (compiled as in my previous post) you have to type:
Code:

.L mylib.so

and you are done.

ROOT 5.15
after compilation you have to do:

1) build a mylib.rootmap file. In order to figure out the needed libraries I use the following script (that uses Axel's black magic):
Code:

#!/bin/bash

CLASS=$1
USERLIB=$2


#from Axel: http://root.cern.ch/phpBB2/viewtopic.php?t=4778
SYMBOLS=$(symbols=`nm -C $USERLIB.so | grep -E ' U T[[:alnum:]_]+::' | sed 's,^.* U \([[:alnum:]_]\+\)::.*$,(\1),'| sort | uniq | tr '\n' '|'`; (for so in $ROOTSYS/lib/*.so; do nm -C -D --defined-only $so | grep -E 'T ('$symbols')::' > /dev/null && echo $so; done )| sort | uniq )

#remove $ROOTSYS
SSYMBOLS=$(echo $SYMBOLS | sed s="$ROOTSYS/lib/"==g)

#now output rootmap
echo -n "Library.$CLASS:       $USERLIB.so "
for ROOTLIB in $SSYMBOLS ; do
    echo -n "$ROOTLIB "
done
echo ""

with a command like
Code:

./do_map Class1 mylib >   mylib.rootmap
./do_map Class2 mylib >> mylib.rootmap
....


it produces a file mylib.rootmap like
Code:

Library.Class1:       mylib.so libCore.so libGpad.so libGraf.so libGui.so libHist.so libMatrix.so libPhysics.so libRIO.so libTree.so
Library.Class2:       mylib.so libCore.so libGpad.so libGraf.so libGui.so libHist.so libMatrix.so libPhysics.so libRIO.so libTree.so


2) add the directory where your library resides to the LD_LIBRARY_PATH environment variable

3) if now you type
Code:

root
c1=new Class1()

it works Very Happy

4) if instead you write (like for root <5.15)
Code:

root
.L /home/users/....../mylib.so

it complains for missing symbols.... ok, I will use method 3) for root >=5.15


I don't know if this is the smartest way to have the job done (probably not) but at least it works in an automatic way with my "real-life" library (about 30 classes that use many features of ROOT).

Thank you for the help!!
Luigi
Back to top
View user's profile Send private message
pcanal



Joined: 27 Aug 2003
Posts: 3586
Location: Fermilab

PostPosted: Fri Aug 03, 2007 20:25    Post subject: Reply with quote

Hi,

Please note that the original limitation:
Quote:
The 'issue' comes from the fact that you library and class have the same name. As a work around you should name your library libclass.so.
is now lifted/removed in the CVS repository.

Cheers,
Philippe
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Root Talk Forum Index -> ROOT Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group