Script including own classes and additional dynamic libraries

Dear all

I have an issue loading a macro file with several functions. The script includes headers that belong to a ROOT-based library called H5root. Furthermore, the library itself uses HDF5.
When trying to load the macro, I first load the libraries, i.e.

root [0] gSystem->Load(“libhdf5”);
root [1] gSystem->Load(“libh5root”);

and then execute

root [2] .L myfile.C

In this case it returns an error message that some base class of the H5root library has incomplete type. If I instead also include the header in the command line, i.e.

root [0] gSystem->Load(“libhdf5”);
root [1] gSystem->Load(“libh5root”);
root [2] #include "myHeader.h"
root [3] .L myfile.C

it works fine. The headers are however also included in the macro file at the top. What is happening there? I do not understand what’s going on.

Btw, I’ m using root/6.08.02.

Best,
Matthias

That is indeed weird. Does libh5root contain a dictionary of myHeader.h?

Cheers, Axel.

We have a dictionary (*.pcm) in the directory where libh5root.so is. All classes are included. The command in the Makefile is

rootcling -f TH5MainDict.cc -c -I$(top_srcdir)/src ${H5root_header_files}

where ${H5root_header_files} has all header files plus the H5rootLinkDef.h that contains

#pragma link C++ class myHeader+;

Best,
Matthias

Hi,

Can you post the actual errors? Do you have the code up say in github?

Axel.

We do have the code of the library in a repository but this is not open to the public. The first part of the error message is

root [0] gSystem->Load("libhdf5");
root [1] gSystem->Load("libh5root");
root [2] .L Track_inBField.C
In file included from TH5MainDict dictionary payload:7:
In file included from /opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/LatticeDialog.h:49:
In file included from /opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/TH5MainFrame.h:29:
/opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/TMDataset.h:72:37: error: base class has incomplete type
class TMDataset : public /*TObject*/DatasetBase {
                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
/opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/DatasetBase.h:25:7: note: definition of 'DatasetBase' is not
      complete until the closing '}'
class DatasetBase : public TObject {
      ^
In file included from TH5MainDict dictionary payload:7:
In file included from /opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/LatticeDialog.h:49:
In file included from /opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/TH5MainFrame.h:42:
/opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/StatDataset.h:52:28: error: base class has incomplete type
class StatDataset : public DatasetBase {
                    ~~~~~~~^~~~~~~~~~~
/opt/psi/Compiler/H5root/1.3.2rc5/gcc/5.4.0/include/DatasetBase.h:25:7: note: definition of 'DatasetBase' is not
      complete until the closing '}'
class DatasetBase : public TObject {
      ^
Error in <TInterpreter::AutoParse>: Error parsing payload code for class DatasetBase with content:

#line 1 "TH5MainDict dictionary payload"

#ifndef G__VECTOR_HAS_CLASS_ITERATOR
  #define G__VECTOR_HAS_CLASS_ITERATOR 1
#endif

#define _BACKWARD_BACKWARD_WARNING_H
#include "LatticeDialog.h"
#include "AnalyseDialog.h"
#include "TOptimize.h"
#include "TRunOpal.h"
#include "TMDataset.h"
#include "TH5Dataset.h"
#include "TH5MainFrame.h"
#include "TH5SliceDialog.h"
#include "TH5BinDialog.h"
#include "TH5LoadDialog.h"
#include "TH5Legend.h"
#include "TH5Style.h"
#include "TH5Util.h"
#include "TPTree.h"
#include "ToolTipReader.h"
#include "TuneDialog.h"
#include "OpalDialog.h"
#include "Table/Table.h"
#include "Table/TableCell.h"
#include "Table/TableHeader.h"
#include "Table/TableHeaderFrame.h"
#include "BDModel.h"
#include "Elements/conversion.h"
#include "ElementTypes.h"
#include "Elements/Element.h"
#include "Elements/Collimator.h"
#include "Elements/CollimatorCE.h"
#include "Elements/CollimatorE.h"
#include "Elements/CollimatorXY.h"
#include "Elements/Degrader.h"
#include "Elements/Drift.h"
#include "Elements/Foil.h"
#include "Elements/Monitor.h"
#include "Elements/Profile.h"
#include "Elements/HaloMonitor.h"
#include "Elements/Quadrupole.h"
#include "Elements/SBend.h"
#include "Elements/Steerer.h"
#include "Elements/SteererX.h"
#include "Elements/SteererY.h"
#include "Elements/Slit.h"
#include "Elements/SlitX.h"
#include "Elements/SlitY.h"
#include "ConnectDialog.h"
#include "LatticeReader.h"
#include "DegraderDialog.h"
#include "DataBaseHeaders.h"
#include "DataBase/DataBaseHandler.h"
#include "DataBase/PROSCAN.h"
#include "DataBase/HIPA.h"
#include "TuneHandler.h"
#include "TuneXML.h"
#include "TuneTDS.h"
#include "TimeStep/TimeStepDialog.h"
#include "TimeStep/Command.h"
#include "TimeStep/RemoveCommand.h"
#include "TimeStep/InsertCommand.h"
#include "DatasetBase.h"
#include "DockableFrame.h"
#include "SublineDialog.h"
#include "DistributionDialog.h"
#include "RogerTools.h"
#include "StatDataset.h"

Thanks, now I see what’s happening:

while parsing DatasetBase.h, ROOT automatically loads the library containing the dictionary for TMDataset. That triggers parsing of TMDataset.h which fails because that header needs DatasetBase.

I’d simply put R__LOADL_LIBRARY(libContainingTH5MainDict) at the top of Track_inBField.C - that should do.

Axel.

I’ve just put R_LOAD_LIBRARY(libh5root) at the top. Unfortunately, it returns the same error. Isn’t it anyway loaded if I perform gSystem->Load("libh5root"); before calling the macro?

Best,
Matthias

Does TMDataset.h have an include of DatasetBase.h (of whatever the name is)?

Yes, it does include the DatasetBase.h.

If I rewrite the code such that it does not directly include the DatasetBase.h in the TMDataset.h file, I obtain the same issue.

Best,
Matthias

Hi Matthias,

Is TH5MainDict in libh5root? And that contains the dictionary for TMDataset, right? But where is the dictionary for DatasetBase, is there one?

Cheers, Axel.

Hi Axel

The rootcling command in a previous post of mine creates the TH5MainDict.cc that is part of libh5root. It contains the TMDataset and DatasetBase. We used libh5root the same way already with ROOT5. There, it worked fine.

Best,
Matthias

In case of including the header file in the command prompt of ROOT (as initially stated), it loads the macro file fine. There, it does not matter if the header file is also included in the macro file or not.

Best,
Matthias

Hi Matthias,

This is really strange. Which OS is that?

I’m afraid I won’t be able to solve that without being able to reproduce it… Do you think you can come up with a stripped-down example exhibiting this issue?

Axel.

It’s Scientific Linux release 6.8 (Carbon)

I can try setting up an example. I’m not sure if I can reproduce it.

Best,
Matthias

It’s either that or you need to give me a chance to debug it in place.

Axel.

I can give you a link where you can download a binary that you can use. We already tested the binary on another system (Ubuntu/16.04) and could reproduce the error there. Additionally, we can send you a tarball of the source. However, we would like to send you all these instructions and files via e-mail since we don’t want to put it into the tracker. Is this ok for you?

Best,
Matthias

In this case we’re missing the rootmap file. Can you create one for libh5root.so, using rootcling, and place it next to the library? See rootcling -h - the flags you want are -rmf and -rml.

I tried the case “load the libraries then .L the script” and a rootmap file fixed that.

Could you confirm?

Cheers, Axel.

And apologies for the super-long silence!