How to compile/link two .cxx files together into one shared library?

Hi all,

Normally, in a macro that I run interactively, I use the following to compile my classes:
gROOT->LoadMacro(“classA.cxx++”);
gROOT->LoadMacro(“classB.cxx++”);

This stops working when the two classes need to be linked. (I get linker errors: undefined symbols…)
Is there an easy way to compile the two classes together, instead of doing it individually one after the other, creating two separate .so libraries?

Thanks!


ROOT Version: 5.34
Platform: Linux


an easy way:

$> cat all.cxx
#include "classA.cxx"
#include "classB.cxx"

and then:

gROOT->LoadMacro("all.cxx++");

should work.

Thank you sbinet,

I had to do some tweaking but your simple suggestion seems to work for now.
What I had to alter was:

  1. Remove the ClassImp statements in all sources (was getting some redefinition error statements) – but from my understanding these aren’t crucial unlike the ClassDef
  2. After compilation of all.cxx, I also need to load in the .cxx’s
gROOT->LoadMacro("all.cxx++");
gROOT->LoadMacro("classA.cxx");
gROOT->LoadMacro("classB.cxx");
  1. And finally, had to remove some external .h includes from the individual sources and move them to the all.cxx

A little bit cumbersome, but seems to work for now.
Again, thanks a lot!

Ah, seems I jumped to conclusions too early.

With the suggested method, I run into problems if I start declaring classB instances anywhere in the source of classA. (again getting linkage errors: dlopen error: /home/./myClasses_cxx.so: undefined symbol: _ZTV10myClassB )

If I declare them in the header it works fine but that is of course not optimal because in some cases I want the instances to be declared only locally.

Any other ideas/suggestions ?
Thanks!

Do I understand it correctly that, when you say “two classes need to be linked”, you actually mean that you created “circular references” / " circular dependencies"?

Yes that’s right, Wile.

So, redesign your source code so that you get rid of it.

Uh but it’s kind of not doable in my case.
classA is an analysis handler which handles I/O and utility functions, classB is an actual analysis code. Obviously these need to be able to talk to each other and pass stuff to each other.

So per Wile’s suggestion I changed my code design and implemented an abstract base class for one of the classes.
So now classA depends on an abstract classBinterface, and a concrete classB (which inherits from classBinterface) depends on classA. Then there are no circular dependencies and I can work with:

gROOT->LoadMacro("classBinterface.cxx");
gROOT->LoadMacro("classA.cxx");
gROOT->LoadMacro("classB.cxx");

Everything seems to compile well now and A and B can now call each other’s functions without any problems.

Thank you Wile for pushing me in the right direction.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.