Making shared library with functions in a namespace

Hi,

I’m trying to add to one of my shared libs a namespace of functions like this:

namespace KVTGIDFunctions
{
Double_t chiosi_Z(Double_t *x, Double_t *par);
Double_t tassangot_Z(Double_t *x, Double_t *par);
Double_t tassangot_A(Double_t *x, Double_t *par);
Double_t pawlowski_Z(Double_t *x, Double_t *par);
Double_t pawlowski_A(Double_t *x, Double_t *par);
}

It seems to me that TMath is done exactly the same way, so I copied
from TMath.cxx the

#if !defined(R__ALPHA) && !defined(R__SOLARIS) && !defined(R__ACC)
NamespaceImp(KVTGIDFunctions)
#endif

macro in order to have HTML documentation, and in my LinkDef file
I added

#pragma link C++ namespace KVTGIDFunctions;

again based on the way TMath is compiled in ROOT. I didn’t see anything else special about TMath (there is no ClassDef or ClassImp macro in the source - it’s not a class, so that seems logical enough ).

Everything goes OK, then when I try to load the library I get

root [0] .L libKVMultiDet.so
dlopen error: /space/indra/franklan/root/lib/libKVMultiDet.so: undefined symbol: _ZN15KVTGIDFunctions4ROOT20GenerateInitInstanceEv
Load Error: Failed to load Dynamic link library /space/indra/franklan/root/lib/libKVMultiDet.so
*** Interpreter error recovered ***

Can anybody tell me what I forgot ?
Cheers
John

PS. ROOT CVS version checked out this morning (5.03/01), compiled on Scientific Linux with gcc 3.2.3 :laughing:

It looks like you library does not contains the compiled dictionary (i.e. you need to run rootcint and compile the result!).

Philippe.

Yes, of course. That’s not the problem.
This is what I do (output from command ‘make’):

Generating dictionary KVMultiDetDict.cpp…
rootcint -v -f KVMultiDetDict.cpp -c -p -Ibase -Icalibration -Idaq_cec -Idb -Idetectors -Ievents -Igeometry -Igui -Iidentification -Iparticles base/KVBase.h base/KVList.h base/KVRList.h calibration/KVCalibrator.h daq_cec/KVACQParam.h daq_cec/KVModule.h daq_cec/KVRegBinary.h daq_cec/KVRegister.h db/KVDataBase.h db/KVDBKey.h db/KVDBRecord.h db/KVDBTable.h detectors/KVDetector.h detectors/KVMaterial.h detectors/KVTarget.h detectors/KVTelescope.h events/KVDetectorEvent.h events/KVEvent.h events/KVReconstructedEvent.h events/KVTestEvent.h geometry/KVGroup.h geometry/KVLayer.h geometry/KVMultiDetArray.h geometry/KVPosition.h geometry/KVRing.h gui/KVBrowser.h gui/KVBrowserNameDialog.h gui/KVBrowserWidget.h gui/KVDataBaseBrowser.h gui/KVDetectorBrowser.h gui/KVLayerBrowser.h gui/KVMultiDetBrowser.h gui/KVRingBrowser.h gui/KVWidget.h gui/KVWidgetList.h identification/KVIDGrid.h identification/KVIDGridManager.h identification/KVIDLine.h identification/KVIDTelescope.h identification/KVIDZAGrid.h identification/KVIDZALine.h identification/KVIDZGrid.h identification/KVIDZLine.h identification/KVTGID.h identification/KVTGIDFunctions.h identification/KVTGIDZA.h identification/KVTGIDZ.h particles/KV2Body.h particles/KVNucleus.h particles/KVParticle.h particles/KVReconstructedNucleus.h KVMultiDetLinkDef.h
Info: Class KVBase: Do not generate Streamer() [*** custom streamer ]
Info: Class KVCalibrator: Do not generate Streamer() [
custom streamer ]
Info: Class KVReconstructedNucleus: Do not generate Streamer() [
custom streamer ]
Info: Class KVReconstructedEvent: Do not generate Streamer() [
custom streamer ***]
g++ -O -Wall -fPIC -pthread -I/space/indra/franklan/root/include -g -Ibase -Icalibration -Idaq_cec -Idb -Idetectors -Ievents -Igeometry -Igui -Iidentification -Iparticles -c -o KVMultiDetDict.o KVMultiDetDict.cpp
g++ -shared -O base/KVBase.o base/KVList.o base/KVRList.o calibration/KVCalibrator.o daq_cec/KVACQParam.o daq_cec/KVModule.o daq_cec/KVRegBinary.o daq_cec/KVRegister.o db/KVDataBase.o db/KVDBKey.o db/KVDBRecord.o db/KVDBTable.o detectors/KVDetector.o detectors/KVMaterial.o detectors/KVTarget.o detectors/KVTelescope.o events/KVDetectorEvent.o events/KVEvent.o events/KVReconstructedEvent.o events/KVTestEvent.o geometry/KVGroup.o geometry/KVLayer.o geometry/KVMultiDetArray.o geometry/KVPosition.o geometry/KVRing.o gui/KVBrowser.o gui/KVBrowserNameDialog.o gui/KVBrowserWidget.o gui/KVDataBaseBrowser.o gui/KVDetectorBrowser.o gui/KVLayerBrowser.o gui/KVMultiDetBrowser.o gui/KVRingBrowser.o gui/KVWidget.o gui/KVWidgetList.o identification/KVIDGrid.o identification/KVIDGridManager.o identification/KVIDLine.o identification/KVIDTelescope.o identification/KVIDZAGrid.o identification/KVIDZALine.o identification/KVIDZGrid.o identification/KVIDZLine.o identification/KVTGID.o identification/KVTGIDFunctions.o identification/KVTGIDZA.o identification/KVTGIDZ.o particles/KV2Body.o particles/KVNucleus.o particles/KVParticle.o particles/KVReconstructedNucleus.o KVMultiDetDict.o -L/space/indra/franklan/root/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lGui -pthread -lm -ldl -rdynamic -o libKVMultiDet.so

The namespace definition I posted first is in KVTGIDFunctions.h.
KVTGIDFunctions.cpp contains the implementation of the functions,
as well as the NamespaceImp macro, à la TMath.

Are the options to rootcint OK for namespaces ?

I’ve narrowed it down :
I only get the load error if I include NamespaceImp(KVTGIDFunctions) in KVTGIDFunctions.cpp.
I implemented this exactly the same way as in TMath.cxx - I even put the “Class Description” comment block before the macro instead of after, because that’s the way it’s done in TMath.cxx.
So there must be something else in the TMath source that I missed.
Any offers ?

The missing symbol:

echo _ZN15KVTGIDFunctions4ROOT20GenerateInitInstanceEv | c++filt
KVTGIDFunctions::ROOT::GenerateInitInstance()

should be defined in the dictionary. Is it?

Are any of the symbol really getting in the dictionary?

Philippe.

PS. The NamespaceImp is only needed for documentation purpose, so you could leave it of … if the dictionary is really well formed …

Hi Philippe

Here is what’s in the dictionary :

namespace KVTGIDFunctions {
   namespace ROOT {
      inline ::ROOT::TGenericClassInfo *GenerateInitInstance();
      static void KVTGIDFunctions_Dictionary();

      // Function generating the singleton type initializer
      inline ::ROOT::TGenericClassInfo *GenerateInitInstance()
      {
         static ::ROOT::TGenericClassInfo 
            instance("KVTGIDFunctions", 0 /*version*/, "identification/KVTGIDFunctions.h", 47,
                     ::ROOT::DefineBehavior((void*)0,(void*)0),
                     &KVTGIDFunctions_Dictionary, 0);
         return &instance;
      }
      // Static variable to force the class initialization
      static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstance(); R__UseDummy(_R__UNIQUE_(Init));

      // Dictionary for non-ClassDef classes
      static void KVTGIDFunctions_Dictionary() {
         GenerateInitInstance()->GetClass();
      }

   }
}

As I said in my last post, things work fine if I just leave out “NamespaceImp”, but I would really like to have HTML documentation for this namespace,
as much for myself as for the rest of my collaboration. And then it’s frustrating to see something work for TMath but not for me… :wink:

Hi,

Something is odd … Please send me a way to reproduce the problem.
Cheers,
Philippe.

Hi Philippe

I’m sending you a .tgz with all the necessary files.
Unpack it, then in the top-level directory type ‘make’.
The shared lib libKVMultiDet.so will be in the lib/ directory.

The two files defining the namespace are
KVMultiDet/identification/KVTGIDFunctions.h
KVMultiDet/identification/KVTGIDFunctions.cpp

The LinkDef file is
KVMultiDet/KVMultiDetLinkDef.h

Good luck!
Thankyou
John
TestKaliVeda.tar.gz (255 KB)

Hi,

The difference between your case and the TMath case is that your dictionary is built with -O. Make sure that it is NOT built with -O and the problem goes away.

Cheers,
Philippe.

PS. A new implementation of THtml is nearing completion and will not really on ClassImp

Hi Philippe

Thanks a lot, that works fine. I remove the “-O” flag from the CXXFLAGS given by $ROOTSYS/test/Makefile.arch and use this non-optimised version CXXFLAGS_NOOPT to compile my dictionaries, while compiling everything else with the ususal CXXFLAGS.

Cheers
John 8)