Dear experts,
I am having trouble creating a shared library that I want to use in Python, and this problem appears when I call functions in other .cxx file that don’t belong to a class.
Since I don’t have permission to share all the code, I’ll just schematize which is the problem.
I have the following package structure:
PackageName
|
- lib/
- obj/
- utils
| |
| - MyMasterFile.py
|
- Root
| |
| - ClassA.cxx
| - ClassB.cxx
| - UtilsFunctions.cxx
| - LinkDef.h
|
- Package
| |
| - ClassA.h
| - ClassB.h
| - UtilsFunctions.h
| - ProgressBar.h
|
- Makefile
The source file UtilsFunctions contains functions that will be called from ClassB and maybe from other python files (if that’s possible). In addition to that, ClassB will always be called from ClassA. So here’s the calling structure:
//============================================================
// In Root/ClassA.cxx
#include "ClassA.h"
void ClassA::doSomething()
{
ClassB foo();
foo.doSomethingInB();
}
//============================================================
// In Package/ClassA.h
#ifndef CLASSA_H
#define CLASSA_H
#include "Package/ClassB.h"
class ClassA {
public:
void doSomething();
}
#endif
//============================================================
// In Root/ClassB.cxx
#include "ClassB.h"
void ClassB::doSomethingInB()
{
float val = Function1();
}
//============================================================
// In Package/ClassB.h
#ifndef CLASSB_H
#define CLASSB_H
#include "Package/UtilsFunctions.h"
class ClassB {
public:
void doSomethingInB();
}
#endif
//============================================================
// In Root/UtilsFunctions.cxx
void Function1()
{
# calculate something here
}
//============================================================
// In Package/UtilsFunctions.h
#ifndef UTILSFUNCTIONS_H
#define UTILSFUNCTIONS_H
void Function1()
#endif
# In utils/MyMasterFile.py
import ROOT
ROOT.gSystem.Load("libPackageName.so")
tool = ROOT.ClassA()
tool.doSomething()
The LinkDef.h
file contains the following:
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclass;
#pragma link C++ class ClassA+;
// #pragma link C++ class ClassB+;
// #pragma link C++ defined_in "UtilsFunctions.h"; (this I don't know if I need to comment or not)
#endif
And finally, in my Makefile I compile all .cxx
files to object files, then the dictionary is created and it’s all linked. All compilation goes well, but when I run the python file I get a message (pointing to ClassA in the .py
file) saying that ClassA is not defined:
cling::DynamicLibraryManager::loadLibrary(): /path/to/tool/PackageName/lib/libPackageName.so: undefined symbol: _ZTIN4ROOT8Internal20TTreeReaderValueBaseE
Traceback (most recent call last):
File "utils/MyMasterFile.py", line 64, in <module>
main()
File "utils/MyMasterFile.py", line 52, in main
tool = ClassA()
NameError: global name 'ClassA' is not defined
I tried before adding UtilsFunctions and everything run fine, so this problem appears when I add these functions. I believe it’s something related with how I generated the dictionary, or compilation, but I can’t decipher it. Also I leave my Makefile
attached (I added the .txt extension so I can upload it )Makefile.txt (1.8 KB).
So to conclude, the question is: what can I do to get this thing working using UtilsFunctions?, because I know it works when I don’t add those
Thank you very much in advance!
Cheers!
Francisco
ROOT Version: 6.20/06
Platform: lxplus