| View previous topic :: View next topic |
| Author |
Message |
pad
Joined: 15 Apr 2005 Posts: 39
|
Posted: Sat Apr 14, 2007 20:29 Post subject: Private shared library do not load in ROOT v5.15.04 |
|
|
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 |
|
 |
musinsky
Joined: 07 Feb 2005 Posts: 161 Location: UPJS Kosice, Slovakia
|
Posted: Sun Apr 15, 2007 10:23 Post subject: |
|
|
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 |
|
 |
Axel

Joined: 03 Sep 2003 Posts: 1506 Location: CERN
|
Posted: Sun Apr 15, 2007 12:36 Post subject: |
|
|
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 |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Fri May 11, 2007 9:02 Post subject: |
|
|
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 |
|
 |
Axel

Joined: 03 Sep 2003 Posts: 1506 Location: CERN
|
Posted: Fri May 11, 2007 10:26 Post subject: |
|
|
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 |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Fri May 11, 2007 11:52 Post subject: |
|
|
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?
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
Regards
Luigi
|
|
| Back to top |
|
 |
Axel

Joined: 03 Sep 2003 Posts: 1506 Location: CERN
|
Posted: Fri May 11, 2007 17:36 Post subject: |
|
|
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 |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Fri May 11, 2007 18:21 Post subject: |
|
|
Dear Axel,
thank you for the reply and for the (black) magic
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 )
Luigi
|
|
| Back to top |
|
 |
pcanal
Joined: 27 Aug 2003 Posts: 3586 Location: Fermilab
|
Posted: Sat May 12, 2007 6:52 Post subject: |
|
|
Hi,
Keep only the line: | Code: | | Library.myclass: myclass.so libHist |
Cheers,
Philippe.
|
|
| Back to top |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Mon May 14, 2007 10:42 Post subject: |
|
|
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......
Luigi
|
|
| Back to top |
|
 |
pcanal
Joined: 27 Aug 2003 Posts: 3586 Location: Fermilab
|
Posted: Mon May 14, 2007 21:00 Post subject: |
|
|
What about | Code: | | Library.myclass: myclass.so libHist.so | ?
Philippe
|
|
| Back to top |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Tue May 15, 2007 8:50 Post subject: |
|
|
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 |
|
 |
pcanal
Joined: 27 Aug 2003 Posts: 3586 Location: Fermilab
|
Posted: Tue May 15, 2007 22:53 Post subject: |
|
|
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 |
|
 |
luigi

Joined: 04 Sep 2003 Posts: 32 Location: Florence, Italy
|
Posted: Wed May 16, 2007 11:08 Post subject: |
|
|
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:
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
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 |
|
 |
pcanal
Joined: 27 Aug 2003 Posts: 3586 Location: Fermilab
|
Posted: Fri Aug 03, 2007 20:25 Post subject: |
|
|
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 |
|
 |
|