Skip to content

ROOT Dict Generation: Solve Issues with Inline Headers

Simon Spannagel requested to merge root_dict_generate into master

We have/had some issues with the generated ROOT dictionary for objects if the original source header files are not available anymore at runtime:

|05:48:44.488|  (STATUS) Initialized PRNG with configured seed 0
Error in cling::AutoLoadingVisitor::InsertIntoAutoLoadingState:
   Missing FileEntry for MCTrack.hpp
   requested to autoload type allpix::MCTrack
Error in cling::AutoLoadingVisitor::InsertIntoAutoLoadingState:
   Missing FileEntry for MCParticle.hpp
   requested to autoload type allpix::MCParticle
Error in cling::AutoLoadingVisitor::InsertIntoAutoLoadingState:
   Missing FileEntry for DepositedCharge.hpp
   requested to autoload type allpix::DepositedCharge
Error in cling::AutoLoadingVisitor::InsertIntoAutoLoadingState:
   Missing FileEntry for Pixel.hpp
   requested to autoload type allpix::Pixel
Error in cling::AutoLoadingVisitor::InsertIntoAutoLoadingState:
   Missing FileEntry for Pulse.hpp
   requested to autoload type allpix::Pulse

There seem to be several small issues.

Issue with correct order of macro commands

We should be first defining the library target via ADD_LIBRARY(MyObjects <...>) and the call the command to generate the dictionary:

ADD_LIBRARY(AllpixObjects <...>)
<...>

ROOT_GENERATE_DICTIONARY(
    AllpixObjectsDictionary
    ${CMAKE_CURRENT_SOURCE_DIR}/MCTrack.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/MCParticle.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/Pixel.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/PixelHit.hpp
    <...>
    MODULE
    AllpixObjects
    LINKDEF
    ${CMAKE_CURRENT_SOURCE_DIR}/Linkdef.h
    OPTIONS
    -inlineInputHeader
    -I${CMAKE_CURRENT_SOURCE_DIR})

I understand this order is the correct one as per here even though I cannot explicitly add the generated AllpixObjectsDictionary.cxx to my library source files. It seems to be added automatically.

Issue with Linkdef order

The dictionary documentation states that the order in the Linkdef file is important:

When using template classes, the order of the pragma statements matters.

We did not obey this so far, since the #pragma definitions for the references between objects (PointerWrapper) were bunched at the end of the file:

#pragma link C++ class allpix::MCTrack + ;
#pragma link C++ class allpix::MCParticle + ;
<...>

#pragma link C++ class allpix::Object::PointerWrapper < allpix::MCTrack> + ;
#pragma link C++ class allpix::Object::PointerWrapper < allpix::MCParticle> + ;

#pragma link C++ class allpix::Object::BaseWrapper < allpix::MCTrack> + ;
#pragma link C++ class allpix::Object::BaseWrapper < allpix::MCParticle> + ;

This means, at the time of processing MCParticle, no proper dictionary (or header) for PointerWrapper<MCTrack> can be found. To correct this, the order must be strictly following dependency patterns - classes that are used or included in other classes need to be placed first such that all dependencies can be resolved also when inlining these headers for dictionary generation:

#pragma link C++ class allpix::MCTrack + ;
#pragma link C++ class allpix::Object::PointerWrapper < allpix::MCTrack> + ;
#pragma link C++ class allpix::Object::BaseWrapper < allpix::MCTrack> + ;

#pragma link C++ class allpix::MCParticle + ;
#pragma link C++ class allpix::Object::PointerWrapper < allpix::MCParticle> + ;
#pragma link C++ class allpix::Object::BaseWrapper < allpix::MCParticle> + ;

<...>

Issue with inlined headers

ROOT dictionaries know two ways of referencing headers at runtime. Either

  • They are included at runtime either from the place the original source files were at compile time or they are searched in ROOT_INCLUDE_PATH
  • They are inlined during dictionary generation and therefore do not need to be present separately on the file system.

We intend to do the latter by specifying the -inputHeaderInline when generating the dictionary. This is also working, however, the headers are inlined in the order they are presented to the macro - and here we have the same problem as for the Linkdef file - the order up till now was rather random, leading to the above error: rootcling walks through them in order and tries to include everything that is missing from the file system. Hence, we need to first include dependent headers and then the ones referencing them.

Sorry, a bit tech-y, but now we should be able to properly run this on installations without having the source headers around and without specifying ROOT_INCLUDE_PATH explicitly, pointing to the post-install header location.

Merge request reports