Bronch not finding class

Hi experts,
I use a compiled class, import it into ROOT, and try to branch from it. The dictionary generation goes just fine, and no errors anywhere. And I can instantiate the class with no problem. But when I try to branch from its, the class cannot be found. I get the error:
Error in TTree::Bronch: Cannot find class:myClass

What am I missing to make ROOT aware of my class?

Here is my header file:

ifndef ROOT_myClass
#define ROOT_myClass

#include <TClassTable.h>
#include <map>
#include "TObject.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TPluginManager.h"
#include "TInterpreter.h"

class TDirectory;

class myClass : public TObject {
 public :
  Float_t energy;
  Float_t time;
  Float_t xpos;
  Float_t ypos;

  myClass();
  virtual ~myClass();
  void init(Option_t *option ="");
  ClassDef(myClass,1);
 
};        

#endif

And here is the c++ code:

#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include "myClass.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TPluginManager.h"
#include "TInterpreter.h"

using namespace std;

ClassImp(myClass);
  
myClass::myClass(){
  cout << "Class instance created" <<  "\n";
}

myClass::~myClass(){
  cout << "Class instance destroyed" <<  "\n";
}

void myClass::init(Option_t * /*option*/) {

}

The LinkDef file is trivial

#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class myClass+;

#endif

Here is the executable code

#include "TTree.h"
#include "myClass.h"

int main(){
 //make a tree
 TTree t4("t4","A Tree with Events");
 // create a pointer to myClass object
 myClass *aEvent = new myClass();
 t4.Branch("event_branch", "myClass", &aEvent,16000,2);
 return 0;
 }

And here is the makefile[code]
#-----------configure ROOT-----------#
ifdef ROOTSYS
include $(ROOTSYS)/etc/Makefile.arch
ROOTINC :=$(shell $(ROOTSYS)/bin/root-config --incdir)
ROOTLIBDIR :=$(shell $(ROOTSYS)/bin/root-config --libdir)
ROOTLDFLAGS :=$(shell $(ROOTSYS)/bin/root-config --ldflags)
ROOTCFLAGS :=$(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS := $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTLINK = $(ROOTLIBS) $(ROOTCFLAGS) $(ROOTLDFLAGS) -I$(ROOTINC)
else
@echo "NO ROOTSYS!"
endif

#--------configure compiler----------#
CXX = g++
CFLAGS = $(ROOTLINK)
CFLAGS += -O2 -Wall -Wno-write-strings
LIBS = -lm -lz -lutil -lnsl -lpthread

.SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)

#----------configure the Event class-----------#
EVENTO = myClass.$(ObjSuf) EventDict.$(ObjSuf)
EVENTS = myClass.$(SrcSuf) EventDict.$(SrcSuf)
EVENTSO = myClass.$(DllSuf)
EVENT = myClass$(ExeSuf)
EVENTLIB = $(shell pwd)/$(EVENTSO)
#MAINEVENTO = MainEvent.$(ObjSuf)
#MAINEVENTS = MainEvent.$(SrcSuf)

PROGRAMS= myApp

#--------object declaration----------#
OBJECTS := $(EVENTO)
#OBJECTS += $(MAINEVENTO)
SHAREDOBJECTS = $(EVENTSO)

default: all

all: $(PROGRAMS)

$(EVENTSO): $(EVENTO)
@echo “compiling $@”
$(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ $(EXPLLINKLIBS)
@echo “$@ done”
@echo “----------------------------------”

$(EVENT): $(EVENTSO)
@echo “compiling $@”
$(LD) $(ROOTLINK) $(LDFLAGS) $(EVENTO) $(LIBS) $(OutPutOpt) $@ $(MT_EXE)
$(MT_EXE)
@echo “$@ done”
@echo “----------------------------------”

analyzerEvent.$(ObjSuf): myClass.h

EventDict.$(SrcSuf): myClass.h LinkDef.h
@echo “Generating dictionary $@…”
@rootcint -f $@ -c $^
@echo “$@ done”
@echo “-------------------------------”

.$(SrcSuf).$(ObjSuf):
@echo “Compiling $@”
$(CXX) $(CFLAGS) -c $<
@echo “-----------------------------------------------------”

myApp: myApp.cxx $(OBJECTS) $(SHAREDOBJECTS)
@echo “Comiling myApp”
$(CXX) $(CFLAGS) -o myApp myApp.cxx $(OBJECTS) $(SHAREDOBJECTS)
@echo “-----------------------------------------------------”

clean::
rm -f *.o ~ #
@rm -f $(OBJECTS) core
@rm -f $(SHAREDOBJECTS) core
rm -f $(PROGRAMS)
[/code]

Hi,

The problem is likely on the line:$(CXX) $(CFLAGS) -o myApp myApp.cxx $(OBJECTS) $(SHAREDOBJECTS) where your executable is linking directly against the .o that are also in the shared library. On some platform, the linker drop any unused symbols. In this case this means that the .o file for the dictionary (which is never directly reference by other .o files) is dropped … resulting in the missing dictionary message.

Instead try:$(CXX) $(CFLAGS) -o myApp myApp.cxx $(OBJECTS) $(EVENTSO)

Cheers,
Philippe.

Thanks for fast reply!

Alas it still gives me the same error when I put .so dependence in by hand.

With the attached “makefile”, try:
make clean ; make
makefile.txt (2.07 KB)

I tried and I get the same error. Thanks again for the attention!

Post here the full output from:
make clean ; make ; ./myApp

[code]
rm -f *.o ~ #
rm -f myApp
c++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -c -o myClass.o myClass.cpp
Generating dictionary EventDict.cxx…
EventDict.cxx done

Compiling EventDict.o
c++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -c EventDict.cxx

Comiling myApp
c++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -o myApp myApp.cxx myClass.o EventDict.o -L/common/lib/root-5.34.23/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic -lm -lz -lutil -lnsl -lpthread

Class instance created
Error in TTree::Bronch: Cannot find class:myClass[/code]

Try the attached “myApp.cxx”.
myApp.cxx (412 Bytes)

I use that myApp.cxx and the included makefile. It gives:

Class instance created
Error in <TTree::Bronch>: Cannot find class:myClass
Class instance destroyed

makefile.txt (2.1 KB)

[quote]c++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -o myApp myApp.cxx myClass.o EventDict.o -L/common/lib/root-5.34.23/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic -lm -lz -lutil -lnsl -lpthread[/quote]I am still seeing the EventDict.o and not the name of the shared library on the command line … This has the same problem has the original. Try with:myApp: myApp.cxx $(EVENTSO) @echo "Comiling myApp" $(CXX) $(CXXFLAGS) -o myApp myApp.cxx $(EVENTSO) $(LIBS) @echo "-----------------------------------------------------"
(and send us the resulting output).

Cheers,
Philippe.

If you link against the shared library (instead of all objects), you will get:
./myApp: error while loading shared libraries: myClass.so: cannot open shared object file: No such file or directory

P.S. I improved my version of the “makefile” a bit (see my first post here), but I don’t think it will fix your problem (it seems to me that it is your ROOT version specific -> 5.34/23 is quite old, I tries 5.34/34 and 6.06/02).

I had addressed the problem with there being no .so in the makefile. The makefile in the my last post makes the dependency on the .so file. If I use that makefile. It gives the same error. Here is compile output:

g++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings   -c -o myClass.o myClass.cpp
Generating dictionary EventDict.cxx...
EventDict.cxx done
-------------------------------
Compiling EventDict.o
g++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -c EventDict.cxx
-----------------------------------------------------
compiling myClass.so
c++ -shared -O2 -m32 myClass.o EventDict.o -o  myClass.so 
myClass.so done
----------------------------------
Comiling myApp
g++ -O2 -Wall -fPIC -pthread -m32 -I/common/lib/root-5.34.23/include -pthread -m32 -I/common/lib/root-5.34.23/include -O2 -Wall -Wno-write-strings -o myApp myApp.cxx myClass.so -L/common/lib/root-5.34.23/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic -lm -lz -lutil -lnsl -lpthread myClass.o EventDict.o
--

I check with the option Philippe provides to make sure and it gives the same error.

You confirm that the code works for near versions of ROOT?

Hi,

Make sure that EventDict.o is also not on the command line.

What does ldd myApp prints?

[quote]./myApp: error while loading shared libraries: myClass.so: cannot open shared object file: No such file or directory
[/quote]Most likely neither dot (’.’) nor the current directory are on the LD_LIBRARY_PATH

Cheers,
Philippe.

The ldd command gives

linux-gate.so.1 => (0xb77df000) myClass.so => /net/data2-4/testing/pocanic/mgv4ce/myClass/analyzer/src/test/myClass.so (0xb77d3000) libCore.so => /common/lib/root-5.34.23//lib/libCore.so (0xb708c000) libCint.so => /common/lib/root-5.34.23//lib/libCint.so (0xb6ab5000) libRIO.so => /common/lib/root-5.34.23//lib/libRIO.so (0xb67e1000) libNet.so => /common/lib/root-5.34.23//lib/libNet.so (0xb669e000) libHist.so => /common/lib/root-5.34.23//lib/libHist.so (0xb616e000) libGraf.so => /common/lib/root-5.34.23//lib/libGraf.so (0xb5f4f000) libGraf3d.so => /common/lib/root-5.34.23//lib/libGraf3d.so (0xb5e56000) libGpad.so => /common/lib/root-5.34.23//lib/libGpad.so (0xb5d78000) libTree.so => /common/lib/root-5.34.23//lib/libTree.so (0xb5b77000) libRint.so => /common/lib/root-5.34.23//lib/libRint.so (0xb5b49000) libPostscript.so => /common/lib/root-5.34.23//lib/libPostscript.so (0xb5adf000) libMatrix.so => /common/lib/root-5.34.23//lib/libMatrix.so (0xb58b3000) libPhysics.so => /common/lib/root-5.34.23//lib/libPhysics.so (0xb582f000) libMathCore.so => /common/lib/root-5.34.23//lib/libMathCore.so (0xb55c9000) libThread.so => /common/lib/root-5.34.23//lib/libThread.so (0xb5586000) libdl.so.2 => /lib/libdl.so.2 (0x4f9e2000) libm.so.6 => /lib/libm.so.6 (0x4f9b6000) libz.so.1 => /lib/libz.so.1 (0x4fa06000) libutil.so.1 => /lib/libutil.so.1 (0x418f2000) libnsl.so.1 => /lib/libnsl.so.1 (0x41ebb000) libpthread.so.0 => /lib/libpthread.so.0 (0x4f9e9000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4fe0a000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4fbf2000) libc.so.6 => /lib/libc.so.6 (0x4f81d000) /lib/ld-linux.so.2 (0x4f7fb000) libssl.so.10 => /usr/lib/libssl.so.10 (0x41326000) libcrypto.so.10 => /usr/lib/libcrypto.so.10 (0x4ffdb000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x4166a000) libgssapi_krb5.so.2 => /lib/libgssapi_krb5.so.2 (0xb54fa000) libkrb5.so.3 => /lib/libkrb5.so.3 (0xb541d000) libcom_err.so.2 => /lib/libcom_err.so.2 (0x411bd000) libk5crypto.so.3 => /lib/libk5crypto.so.3 (0xb53f2000) libresolv.so.2 => /lib/libresolv.so.2 (0x4fbac000) libfreebl3.so => /lib/libfreebl3.so (0x4169c000) libkrb5support.so.0 => /lib/libkrb5support.so.0 (0xb53e5000) libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x412b1000) libselinux.so.1 => /lib/libselinux.so.1 (0x4fa27000)

When I explicitly put the absolute pathway to my current directory into the LD_LIBRARY_PATH, I get the same error.

And I make sure .o files are not in command, but error persists.

Hi,

This is odd …

What does root.exe -b -l root [] .L myClass.so root [] c = TClass::GetClass("myClass") root [] c->Print() prints to the screen? Can you attach your EventDict.cxx?

Cheers,
Philippe.

Here is output of interactive

[mgv4ce@node4 test]$ root.exe -b -l
root [0] .L myClass.so
root [1] c = TClass::GetClass("myClass")
(class TClass*)0x0
root [2] c->Print()
Error: illegal pointer to class object c 0x0 2  (tmpfile):1:
*** Interpreter error recovered ***
root [3] 

Many thanks for all the help!
EventDict.cxx (29.4 KB)

puzzling … very puzzling …

Your dictionary file does contain the dictionary for myClass: // Function generating the singleton type initializer static TGenericClassInfo *GenerateInitInstanceLocal(const ::myClass*) { but the library does not seem to contain it and/or does not register it:root [0] .L myClass.so root [1] c = TClass::GetClass("myClass") (class TClass*)0x0.

What doesnm -A myClass.so | grep GenerateInitInstanceLocal | c++filt
prints. In my case I get:$ nm -A myClass.so | grep GenerateInitInstanceLocal | c++filt myClass.so:00000000002089e0 b guard variable for ROOTDict::GenerateInitInstanceLocal(myClass const*)::instance myClass.so:00000000002089d8 b guard variable for ROOTDict::GenerateInitInstanceLocal(myClass const*)::isa_proxy myClass.so:0000000000004e90 t ROOTDict::GenerateInitInstanceLocal(myClass const*) myClass.so:0000000000208a00 b ROOTDict::GenerateInitInstanceLocal(myClass const*)::instance myClass.so:0000000000208b00 b ROOTDict::GenerateInitInstanceLocal(myClass const*)::isa_proxy

Cheers,
Philippe.

Try to run:
echo ${ROOTSYS}
root-config --arch
root-config --cxx
root-config --ld
g++ -v
c++ -v

For the echo I get

[mgv4ce@node4 test]$ echo ${ROOTSYS}
/common/lib/root-5.34.23/
[mgv4ce@node4 test]$ root-config --arch
linux
[mgv4ce@node4 test]$ root-config --cxx
c++
[mgv4ce@node4 test]$ root-config --ld
c++
[mgv4ce@node4 test]$ g++ -v
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) 
[mgv4ce@node4 test]$ c++ -v
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) 
[mgv4ce@node4 test]$ 

When I grep I get

[mgv4ce@node4 test]$ nm -A myClass.so | grep GenerateInitInstanceLocal | c++filt myClass.so:00008978 b guard variable for ROOT::GenerateInitInstanceLocal(myClass const*)::instance myClass.so:00008970 b guard variable for ROOT::GenerateInitInstanceLocal(myClass const*)::isa_proxy myClass.so:00003b50 t ROOT::GenerateInitInstanceLocal(myClass const*) myClass.so:00008980 b ROOT::GenerateInitInstanceLocal(myClass const*)::instance myClass.so:00008a00 b ROOT::GenerateInitInstanceLocal(myClass const*)::isa_proxy

One more check:
which root
which root.exe