Cannot find my rdict.pcm files

I am updating a small ROOT application from ROOT v5 to ROOT v6. Everything compiles and builds without error, but the final executable complains about inability to find the rdict.pcm files.

These rdict.pcm files are new with ROOT v6 and there is barely any documentation on what they are and what I am supposed to do with them.

For example, answers in this forum instruct me to place these files in the same directory
as my shared library. Good advice, but I do not create any shared libraries in my application.
(I do create a static library).

Anyhow, using “strace”, I see that my ROOT v6 application is looking for the rdict.pcm files
in the current directory ("."), in $ROOTSYS/lib and in the system library directories.

Is there any way I can add the actual location of my rdict.pcm files to this search path?

Is there a migration guide (“ROOT v5 to v6 migration for dummies”) where any of this is explained?

K.O.

P.S. The application is this: bitbucket.org/tmidas/rootana, build it using “make -f NMakefile”, run the test program by “cd libAnalyzerDisplay; ./display_example.exe”. (MIDAS package is not required).

Is there any way I can add the actual location of my rdict.pcm files to this search path?

So I force my application to find the correct rdict.pcm files by symlinking them into the current directory,
but this is not good enough.

Now the application complains about not finding a good number of C++ header files from my project.

Why is this? ROOT v5 did not need my header files. ROOTv6 pcm files are supposed to be “pre-compiled header files” replacing the actual header files, yes?

So with strace, I look at where it is looking for the header files - in the current directory, in $ROOTSYS/etc, $ROOTSYS/include, in GCC internal includes, in system include, etc.

How do I add my actual location of header files into this search path?

K.O.

P.S. If I force my application to find the header files by symlinking them into the current directory, the application starts and runs correctly. So I have at least one solution.

K.O.

Hi,

For calling functions, ROOT 6 needs to know about the classes. It doesn’t create big dictionaries like ROOT 5 anymore, with a dictionary function for each class function. Instead, it parses the header.

The plan is indeed to have precompiled headers at some point (C++ modules, actually). Until we have them we need to things to call functions through the interpreter:

  • find the headers at runtime. You can instruct ROOT with an environment variable ROOT_INCLUDE_PATH to look at certain locations. But parsing headers takes time (just like compilation). So
  • ROOT provides a _dict.pcm file which contains enough data to serialize (do I/O / store and read) your classes, without having to parse headers.

Let’s try to find a solution that will work for you. First of all:

  • Do you need to call functions through the interpreter?
  • Do you store objects of your classes to ROOT files?

Cheers, Axel.

We need two things to call functions through the interpreter:

  • find the headers at runtime.
  • ROOT provides a _dict.pcm file which contains enough data to serialize (do I/O / store and read) your classes, without having to parse headers.

Ok. Now it is clearer. In ROOTv5 the dictionary created by rootcint was enough, in ROOTv6 you also need all the .h files and the mysterious pcm files. (what do they do, what’s in them, is this written up somewhere?)

You can instruct ROOT with an environment variable ROOT_INCLUDE_PATH

I confirm this works for finding the .h files.

But for finding the pcm files, I still have to symlink them into my current directory. I looked at the source code of TCling::LoadPCM() and it appears to be impossible for me to provide a custom path for pcm files: it looks at FindLibraryName() which in my case seems to be the name of the application executable and it looks at gSystem->GetDynamicPath() which is probably empty at this point. All this happens before I can do gSystem->AddDynamicPath("/path/to/pcm/files") in my main(). (Try it and have a laugh, then cry).

Let’s try to find a solution that will work for you. First of all:

  • Do you need to call functions through the interpreter?

Yes, we do this: fSaveCanvasButton->Connect(“Clicked()”, “TMainDisplayWindow”, this, “SaveCanvasButtonAction()”);

  • Do you store objects of your classes to ROOT files?

No, we do not do this in this application at this moment. We may do it later though. Does streaming C++ classes into XML and JSON count?

K.O.

P.S. Half the problem is resolved: I do not have to symlink all the .h files, but I still have to symlink the pcm files.

Hi,

the *rdict.pcm files can be put in the LD_LIBRARY_PATH.

Cheers,
Danilo

Hi,

As Danilo said.

The idea is that it’s next to the library. We simply have not thought about providing anything special for binaries. We are discussing what we can do here; I understand that this is especially awkward when all you have is a binary…

Cheers, Axel.

Thank you all for the help, we can now start using ROOTv6. As summary: (please add this to the ROOT documentation)

With ROOTv5 it was possible to build self-contained executables (all the dictionary stuff was linked into the executable itself, no external files required to run). With ROOTv6 this is impossible: executables require access to rdict.pcm and c++ .h files from the same build. If the c++ .h files are updated or the rdict.pcm files are regenerated, existing executables will stop working. In addition, following environment variables must be set, otherwise ROOTv6 will fail to load these required files and the executable will not run correctly:

a) rdict.pcm files are searched through LD_LIBRARY_PATH
b) c++ .h files are searched though ROOT_INCLUDE_PATH

K.O.

Hi,

Danilo will try to embed the pcm file into the dictionary source file, such that you don’t need to take care of an extra file. If that succeeds then it will arrive in v6.10.

I have not forgotten about your request to put that migration info up, I just cannot find the page back (I am sure we had that at some point). I.e. I’m slow but haven’t forgotten! I’ll post the link here once it is published.

Cheers, Axel.