Problems linking TFormula in shared library


ROOT Version: 6.16.00
Platform: CentOS 7
Compiler: g++ 7.3.1 20180303


Dear experts,
In the following minimal example i am trying to build a shared library including TFormula.
When i run the MyClass::dev() method from the shared library in python, I get the error

python: symbol lookup error:<PATH_TO>myclass.so: undefined symbol: _ZN8TFormulaC1EPKcS1_bb

MyClass.h:

    #ifndef MYCLASS_H
    #define MYCLASS_H
    #include "TFormula.h"

    class MyClass {
    public:
        MyClass() {}
        virtual ~MyClass() {}
        void dev();
    private:
        ClassDef(MyClass,1)
    };
    #endif

MyClass.cxx

    #include "Riostream.h"
    #include "MyClass.h"

    void MyClass::dev() 
    {
        TFormula f("F", "[0]**2+[1]**2");
    }

MyClass_LinkDef.h

    #ifdef __CINT__
    #pragma link off all globals;
    #pragma link off all classes;
    #pragma link off all functions;
    #pragma link C++ nestedclasses;
    #pragma link C++ defined_in "MyClass.h";
    #endif

My makefile produces the following commands:

g++ -Wall -Wextra -Woverloaded-virtual -fPIC -W -pipe -Ofast -ftree-vectorize  -pthread -std=c++17 -m64 -I/usr/local/include/root -L/usr/local/lib/root -lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lROOTDataFrame -pthread -Wl,-rpath,/usr/local/lib/root -lm -ldl -rdynamic -lRooFit -lRooStats -lTreePlayer  -c MyClass.cxx -o MyClass.o

rootcint -f myclass_dict.cc -c MyClass.h MyClass_LinkDef.h

g++ -Wall -Wextra -Woverloaded-virtual -fPIC -W -pipe -Ofast -ftree-vectorize  -pthread -std=c++17 -m64 -I/usr/local/include/root -L/usr/local/lib/root -lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lROOTDataFrame -pthread -Wl,-rpath,/usr/local/lib/root -lm -ldl -rdynamic -lRooFit -lRooStats -lTreePlayer -c myclass_dict.cc -I. -o myclass_dict.o

g++ -shared -O3  MyClass.o myclass_dict.o -o myclass.so

Why does TFormula not link properly even though I have included all libraries that are required for TFormula?
Here is an example of the script I am using:

    import ROOT
    from ROOT import gSystem
    gSystem.Load("myclass.so")

    m = ROOT.MyClass() # No problem so far
    m.dev() # Error from above

Hi @VukanJ

You need to include your header before loading the library.

import ROOT
from ROOT import gSystem, gInterpreter
gInterpreter.ProcessLine('#include "MyClass.h"')
gSystem.Load("myclass.so")

Also please note that ROOT 6 does not use cint anymore, so you do not need MyClass_LinkDef and its related step in the makefile. You just need to generate your .so by linking it to ROOT and then run your Python script as described.

Yes, that works perfectly, thank you! :slight_smile: And thanks for the tip!