Get list of checksums and classdef version of all classes in a dictionary

I would like to add some checks to our build/CI system to make sure users don’t forget to increment the ClassDef version if they modify the class layout.

The easiest solution would be if I can specify the checksum/class versions when building the dictionary so that rootcling warns/fails if that doesn’t match with what it sees.

Alternatively I can go over the list of classes after building the dictionary. So the question would be, what is the best way to get a list of all classes which are in a root dictionary (created from a linkdef.h and rootcling) and get their classdef versions and checksums? Ideally something like

for class, version, checksum in get_classes_in_dict():
    # do some comparison with known values

Thanks a lot,

Martin


ROOT Version: 6.20/04
Platform: Ubuntu 18.04/CentOS7
Compiler: GCC 9.3


Hi Martin,

CMSSW (and ART) build system have this feature … but for input expression using the selection xml format.

The easiest way is likely to parse the LinkDef file (i.e. search for #pragma link C++).

The ‘hard’ part is deciding (and maintaining) the “database” of old and current CheckSum (to compare the one being processed).

In the case of CMSSW, it is embedded in the xml file and the “checker” is a process that load the libraries and compare the checksum. The code can be found at: https://github.com/cms-sw/cmssw/tree/master/FWCore/Utilities/scripts

Hi Philippe,

thanks a lot for the example, that helps a lot with the implementation. I will do the extra lazy option and misuse the comments in the linkdef file:

#pragma link C++ class Belle2::BeamParameters+; // checksum=0x94a2b4bc, version=2

Maybe one or two followup questions:

  1. The CMS scripts have some weird “ProcessLine()” parts which I don’t see the necessity for. Do you happen to know if this is historical and not needed anymore?
ROOT.gROOT.ProcessLine("class checkclass {public: int f(char const* name) {TClass* cl = TClass::GetClass(name); bool b = false; cl->GetCheckSum(b); return (int)b;} };")
ROOT.gROOT.ProcessLine("checkclass checkTheClass;")
  1. We have some classes without a ClassDef() in the class header, For example template classes. For these I get a version of -1. Is there a way to set the class version they should have somehow other than the ClassDef() macro?

Yes. There is a couple of ways.

#pragma link C++ options=version(5) class Something+;

or using the RootClassVersion macro.

1 Like

I am not sure why it goes through the ProcessLine but it is used, see https://github.com/cms-sw/cmssw/blob/40e79d8b67fa7637b51bcf5a65ba82e7a24c3675/FWCore/Utilities/scripts/edmCheckClassVersion#L135

Awesome, thanks.

However, and I really hate to do this knowing full well how it is: is there a documentation of these options? I grep-ed through the ROOT code and only found two instances of this being used and so far no luck in finding documentation.

I think I found the code to do it so It seems there’s a few of them (nostreamer, noinputoper, evolution, nomap, stub, version(x)) and they can be added as comma separated values. But I couldn’t find it documented anywhere else.

This would lead me to a different question: Would we want implement the checksum check in the dictionary parsing directly?

We could add a new option checksum(0x324234) to these options. If the option is present the dictionary generation should fail if the result differs from the expectation and print the actual version, checksum vs what was given as checksum.

I guess would be able to modify the pragma options function to add the checksum option but I have no idea how to continue from there.

It’s not urgent, I have a working solution now, I was just wondering whether this is something one might want as a core feature to ensure integrity as multiple experiments started implementing it themselves.

I am not sure how this slip through the craks but indeed I can’t find any either … :frowning:

I guess would be able to modify the pragma options function to add the checksum option but I have no idea how to continue from there.

The check could be added towards when rootcling is about to start writing down the code in the dictionary and issue a Warning (and then the --fail-on-warning can kick in or not).

Cheers,
Philippe.

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