Hi All,
I am having trouble migrating code from ROOT 5.34 (where it runs perfectly) up to ROOT6. Currently, the code compiles fine, but I am having trouble with the linking. I feel like this question is pretty straight forward and might be addressed somewhere, but I have found some contradictory/outdated answers, but none that work quite right.
Here is a breakdown of the situation:
We have libraries A, B, C … X, Y, Z. At compile time, A must be compiled first, and libraries B - Y all depend on A and increasingly on each other. But at run time libA loads libZ which does not depend on A (this is somewhat historical since libZ contains a bunch of style options and is fairly ‘unimportant’.)
So, in ROOT 5, libraries A - Z are independently compiled, and can be compiled in roughly any order (after A). Each library follows the same steps: first the source code, then a dictionary is generated with rootcint, then the shared library is compiled. The last step passes that library along with all the libraries it depends on to rlibmap. For example:
# ROOTCINT
$ rootcint -f K_Dict.cc -c -p -I[INCLUDES] K1.hh K2.hh K3.hh LinkDef.hh
# COMPILE DICTIONARY
$ g++ -c [CXXFLAGS] -o K_Dict.o K_Dict.cc
# COMPILE LIBRARY
# Note that this command does not have any linked libraries (-lA -lC) etc
$ g++ -shared [FLAGS] -I[INCLUDES] K1.o K2.o K3.o K_Dict.o -o libK.so
# CREATE ROOTMAP
$ rlibmap -f -o LIBDIR/libK.rootmap -l libK.so -d libA libC libG -c LinkDef.hh
This created a rootmap file that listed all the classes in libK and all the libraries that need to be loaded in order to load libK.
Ok, so flash to ROOT6. rlibmap is no longer a thing, and rootcint is now a wrapper for rootcling.
So my compile now looks like this:
# ROOTCLING
$ rootcling -rootbuild -f K_Dict.cc -s libK -rmf libK.rootmap -c -p -I[INCLUDES] K1.hh K2.hh K3.hh LinkDef.hh
# COMPILE DICTIONARY
$ g++ -c [CXXFLAGS] -o K_Dict.o K_Dict.cc # same as above
# COMPILE LIBRARY
$ g++ -shared [FLAGS] -I[INCLUDES] K1.o K2.o K3.o K_Dict.o -o libK.so # same as above
So now the problem is that when I try to load the libraries in ROOT:
root [] gSystem->Load("libK")
It complains that symbols (that can be found in libA) are undefined. Now, I can fix the problem if I add “-lA -lC -lG” to the g++ -shared command so that the libraries are explicitly linked, however this would require that things be compiled in the proper order (i.e. that the library exist at compile time.)
So a few questions:
First of all, am I doing something wrong here? Am I missing something obvious?
Second, what is the purpose of the -rml flag to cling? I see that it is optional, and it sounds like it might be relevant?
Third, what is the purpose of the pcm file? It is placed next to the library and rootmap files, but I am not sure what exactly it is doing, other than that the interpreter complains when its not there. Should I be passing the "-m libA_dict.pcm … " flags to rootcling? Since there seems to be no guarantee that the pcm files passed at compile time are the same as those at run time, I wasn’t sure that this was relevant. Again, this would require compiling in the correct order?
Hopefully that was all clear. Thanks in advance.
Cheers,
–Jon