Linking problem to libTree.so

Hi all,
I am trying to compile a code which uses the TTree class. Hence, I execut (*) to compile and link my executable to needed libraries. But the compiler does not realize that I need “-lTree” to be linked to my .o.
I think so because after compiling successfully, I get this (**) runtime error. Besides, the “ldd” command output does not contain libTree.
I cured it by adding gSystem->Load(“libTree.so”) in my .C file, but it is not a wise and permanent solustion.

Can somebody help me understand what is wrong with my linking?

Thanks a lot,
Nadjieh

(*)
ROOTGLIBS =$(shell root-config --glibs) -lMinuit
ROOTCFLAGS =$(shell root-config --cflags)
LIBS = userLibs
HEADERS = userheaders

@echo "Compiling the SelectAndSave .... \n"
$(CXX) SelectAndSave.C -c -o SelectAndSave.o -O0 $(ROOTCFLAGS) -fPIC $(HEADERS)
@echo "Linking ...... \n"
g++ SelectAndSave.o -o SelectAndSave $(ROOTGLIBS) -lEG $(LIBS) -v -g -fPIC -O0 -I/opt/root/include -m64 -pthread $(HEADERS)

(**)
Warning in TClass::TClass: no dictionary for class TTree is available
Warning in TClass::TClass: no dictionary for class TBranchElement is available
Warning in TClass::TClass: no dictionary for class TBranch is available
Warning in TClass::TClass: no dictionary for class TLeafElement is available
Warning in TClass::TClass: no dictionary for class TLeaf is available
Warning in TClass::TClass: no dictionary for class TVirtualIndex is available
Warning in TClass::TClass: no dictionary for class TBranchRef is available
Error in TBufferFile::ReadClassBuffer: class: TNamed, attempting to access a wrong version: 18, object skipped at offset 63
Error in TBufferFile::CheckByteCount: object of class TNamed read too few bytes: 2 instead of 10314
Error in TBufferFile::ReadClassBuffer: class: TNamed, attempting to access a wrong version: 18, object skipped at offset 60
Error in TBufferFile::CheckByteCount: object of class TNamed read too few bytes: 2 instead of 493722
runTree:
Error in TFile::Read: Key not found

*** Break *** segmentation violation

===========================================================
There was a crash.
This is the entire stack trace of all threads:

#0 0x00007f25d3cc811e in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007f25d3c5ee0e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007f25d5c0ae37 in TUnixSystem::StackTrace() () from /opt/root/lib/libCore.so
#3 0x00007f25d5c0d703 in TUnixSystem::DispatchSignals(ESignals) () from /opt/root/lib/libCore.so
#4
#5 0x000000000043c6f5 in PracticalEvent::PracticalEvent(TTree*, TTree*, bool, bool, bool, bool, bool, bool, bool, bool) ()
#6 0x0000000000429fa9 in main ()

The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.

#5 0x000000000043c6f5 in PracticalEvent::PracticalEvent(TTree*, TTree*, bool, bool, bool, bool, bool, bool, bool, bool) ()
#6 0x0000000000429fa9 in main ()

[quote] think so because after compiling successfully, I get this (**) runtime error. Besides, the “ldd” command output does not contain libTree. [/quote]Yes, this would indeed be fatal … Which version of ROOT are you using? What is the value of root-config --glibs? What is your OS?

Philippe.

Hi,
My root version is 5.32.00 and I am using ubuntu 11.4 OS.
The outcome of root-config --glibs is:
-L/opt/root/lib -lGui -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic

It contains lTree …

Thanks,
Nadjieh

Hi Nadjieh,

Ubuntu’s linker by default strips for the linking any libraries that does not have any use in the source being compiled.

What is the content of your main.cxx? (I suspect that there is neither a direct connection to TTree nor is the ROOT environment setup enough to enable the autoloading of (ROOT) libraries.

Cheers,
Philippe.

Hi Philippe,

[quote=“pcanal”]

What is the content of your main.cxx? (I suspect that there is neither a direct connection to TTree nor is the ROOT environment setup enough to enable the autoloading of (ROOT) libraries.

Philippe.[/quote]

Actually it does. I use TTree to read my nTuples and this is where the code crashes at runtime.
This is exactly the strange part. I have

gSystem->Load(“libTree.so”);
TTree* runTree = (TTree*) f->Get(“runTree”);

in my .C file. The code crashes at second line if I comment the first line:

Warning in TClass::TClass: no dictionary for class TTree is available
Warning in TClass::TClass: no dictionary for class TBranchElement is available
Warning in TClass::TClass: no dictionary for class TBranch is available
Warning in TClass::TClass: no dictionary for class TLeafElement is available
Warning in TClass::TClass: no dictionary for class TLeaf is available
Warning in TClass::TClass: no dictionary for class TVirtualIndex is available
Warning in TClass::TClass: no dictionary for class TBranchRef is available
Error in TBufferFile::ReadClassBuffer: class: TNamed, attempting to access a wrong version: 18, object skipped at offset 63
Error in TBufferFile::CheckByteCount: object of class TNamed read too few bytes: 2 instead of 10314
Error in TBufferFile::ReadClassBuffer: class: TNamed, attempting to access a wrong version: 18, object skipped at offset 60
Error in TBufferFile::CheckByteCount: object of class TNamed read too few bytes: 2 instead of 493722
runTree:
Error in TFile::Read: Key not found

I am rather confused with this.

Cheers,
Nadjieh

Hi Nadjieh,

Your ROOT build and/or your ROOT installation is corrupted is some ways (i.e. one possibility is that an older version is still on the PATH or LD_LIBRARY_PATH).

gSystem->Load("libTree.so"); TTree* runTree = (TTree*) f->Get("runTree");The 1st line should never be necessary and even in the case where libTree is either not linked against or automatically load, it should not be leading to a crash …

Can you check that your $PATH variable and $LD_LIBRARY_PATH and $ROOTSYS variable points to a single installation of ROOT and that the location of the ROOT library files (usually $ROOTSYS/lib) contains both .so and .rootmap files?

Cheers,
Philippe.

Hello Philippe,

I have installed the current version (5.32) in /opt/root/ directory. The output for PATH and other variabes you suggested are:
$PATH = /opt/root/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

$ROOTSYS = /opt/root

$LD_LIBRARY_PATH = /opt/root/lib:/home/nadjieh/lib

So I think all paths are consistently pointing to the same directory. I also checked the existence of .rootmap files:
$ l /opt/root/lib/libTree*
/opt/root/lib/libTreePlayer.rootmap /opt/root/lib/libTree.rootmap /opt/root/lib/libTreeViewer.rootmap
/opt/root/lib/libTreePlayer.so* /opt/root/lib/libTree.so* /opt/root/lib/libTreeViewer.so*

which is fine.
Do you think that cleaning the current installation and reinstalling can help? If so, which kind of cleaning command works really cleaner and erase all root-connected things?

Cheers,
Nadjieh

Hi Nadjeh,

Can you load the file and read your TTree with the ROOT executable? root.exe -b -l root [] TFile f("yourfile.root"); root [] TTree *tree; f.GetObject("runTree",tree);

Philippe

Do you create an instance of TApplication in your main? If not, auto-loading of ROOT libraries will not work and you will need to load (some of) them manually, i.e. ‘gSystem->Load(“libTree.so”);’.
Do you have the “/etc/root” subdirectory? If yes, you most probably have Ubuntu’s default version of ROOT installed, which may interfere with your “private” ROOT installation (in “/opt/root”) -> “completely remove” all standard Ubuntu’s ROOT packages (using a “package manager”) - see also [url]ROOT 5.32/00 support

Hi Philippe,

Here it is:

root [1] gSystem->Load(“libPhysics.so”);
root [2] gSystem->Load("~/lib/libToto.so");
root [3] TFile f("~/work/samples/t-chan-Sync/1-TOPTREE.root")
root [4] TTree *tree; f.GetObject(“runTree”,tree);
root [5] tree->GetEntries()
(const Long64_t)1

The first two libraries I load so root recognizes my objects and does not warn about the missing dictionary.
The rest seems fine.

Cheers,
Nadjieh

Hi Pepe,

[quote=“Pepe Le Pew”]Do you create an instance of TApplication in your main?
[/quote]
No I don’t.

[quote=“Pepe Le Pew”]
If not, auto-loading of ROOT libraries will not work and you will need to load (some of) them manually, i.e. ‘gSystem->Load(“libTree.so”);’.[/quote]
Strange! Is it because of ubuntu? I have never used TApplication and I didn’t experience any problem like this before.

No. The outcome of
$l /etc/ | grep root
command is empty. I also tried
$locate config-root
and I got
$ locate root-config
/opt/root/bin/root-config
/opt/root/cmake/scripts/root-config.in
/opt/root/config/root-config.in
/opt/root/man/man1/root-config.1
Cheers,
Nadjieh

So, the problem is … lack of a TApplication (thus no auto-loading of ROOT libraries) AND a new linker type (“unused” libraries given to the linker stage are “stripped” because of the default “–as-needed” flag).
You may try three solutions:

  1. add an instance of TApplication in you main (I presume this is the preferred method):
    grep -r "TApplication " ${ROOTSYS}/test/* ${ROOTSYS}/tutorials/*
  2. load additional required libraries manually (i.e. ‘gSystem->Load(“libTree.so”);’)
  3. add the “–no-as-needed” flag to the linking stage of your application (something like “-Wl,–no-as-needed $(ROOTGLIBS)”)

Hello Pepe,
Thanks a lot for following this issue.
I tried your first suggested option:

and it worked :slight_smile:

Cheers,
Nadjieh

Hy! I stumbled across the same Problem and I#m really to new to everything. Can you tell me exactly what to do??
I just don’t know where to add for example the "-Wl,–no-as-needed " flag, do I have to add it in the compiler or where??
I have a bash script to run run my application.