Compiled ROOT dictionaries

The procedure in Interpreted ROOT dictionaries is fine when you’re prototyping your data structures and other initial development tasks. But at some point it becomes more convenient to compile your dictionaries rather than dynamically interpreting them:

  • Interpreting a ROOT dictionary takes longer than compiling it.

  • If you’re developing a program that you want to be distributed as part of a large project, you may want to distribute compiled binary libraries rather than potentially allowing “mysterious” AutoDict* files to be added to users’ working areas.

  • If you’re developing a program that will be distributed to a computational grid as described in Batch Systems, you may not want the remote jobs to be potentially delayed with interpreting ROOT dictionaries.

The ROOT command for generating a compiled dictionary is rootcling. I find the older rootcling documentation to be a better guide than that the newer page in the first link in this paragraph.

To use rootcling to compile a dictionary, you need to create a LinkDef.h file. Take a look at the file STL_LinkDef.h. The key lines are:

Listing 61: The key LinkDef.h lines for generating a dictionary for STL_TrackList.h and other TTree branches. Compare this with Listing 59.
#pragma link C++ class std::map<int,double>+;
#pragma link C++ class std::tuple<int,int>+;
#pragma link C++ class std::map<std::tuple<int,int>,double>+;

#pragma link C++ struct trackInfo+;
#pragma link C++ class TrackList+;

A LinkDef.h file tells rootcling every C++ class, struct, and non-fundamental C++ type that are present in the objects that we’ll read/write.

Here’s a summary of the commands you’ll see in the comments within STL_LinkDef.h and STLntupleCreateDict.cxx to create a dictionary for the C++ types in STL_TrackList.h.

Listing 62: The commands to generate, compile, and link the dictionary for the example STL_TrackList.h.
rootcling -f STLntupleDict.cxx STL_TrackList.h STL_LinkDef.h
g++ `root-config --cflags --libs` -shared STLntupleDict.cxx -o STLntupleDict.so -fPIC
g++ `root-config --cflags --libs` STLntupleCreateDict.cxx ./STLntupleDict.so -o STLntupleCreateDict

Don’t delete the .pcm files

You’ll note that a .pcm1 file is created as part of the process in Listing 62, STLntupleDict_rdict.pcm. In general, such a file is needed by the corresponding .so file (STLntupleDict.so in this case). If you start moving files around, the .pcm file and .so file should be moved together.

If you know what $LD_LIBRARY_PATH means: You can include a directory containing a .pcm file, in the same way you can with a .so file.

STLntupleCreateDict.cxx is functionally identical to STLntupleCreate.cxx. The only difference it relies on the dictionary for STL_TrackList.h to have been compiled as part of the program, so no gInterpreter lines are needed.

Similarly, STLntupleReadDict.cxx is functionally identical to STLntupleRead.cxx.2

Finally, STLntupleReadDict.py is functionally identical to STLntupleRead.py. Since we can’t compile a Python script with an external C++ library (at least, not in any simple way) we have to use ROOT to load the dictionary library:

gSystem.Load("STLntupleDict.so")

cmake

If the commands in Listing 61 seem long and elaborate to you, you’re right. Fortunately, in a project that’s complex enough to involve ROOT dictionaries, it’s not likely you’d have to have to type them (or rather, copy, paste, edit, and use up-arrow from some other source like Listing 61).

Complex and shared programming projects in UNIX are typically handled using the cmake utility.3 From the ROOT custom I/O page, it seems that equivalent of Listing 61 for a CMakeLists.txt file might be

ROOT_GENERATE_DICTIONARY( STLntupleDict STL_TrackList.h
   LINKDEF STL_LinkDef.h
   MODULE STLntupleReadDict )

Before you copy-and-paste this blindly, bear in mind that:

  • I have not tested that ROOT_GENERATE_DICTIONARY line.

  • Typically a CMakeLists.txt can be quite involved. I made some assumptions about target names and the like.

  • This overall example based on the contents of STL_TrackList.h was intended to be a quick-and-dirty study on my part. I added comments afterwards for this tutorial. My goal was to understand ROOT dictionaries, not to understand cmake.

    That comes next!


1

“PCM” stands for “pre-compiled module”.

It’s surprisingly difficult to find this definition in either the ROOT documentation or via web searches!

2

STLntupleReadDict.cxx is essentially the solution to Exercise 15: Data reduction (working with TTrees). This is another example of how reading ahead can give you all the answers!

3

If you’ve never encountered cmake before, you can think of it as a command-line equivalent of Xcode on MacOS, or the Visual Studio platform.