I know this has been discussed before and I have searched through I think most posts related to this issue.
I am using root 6 and trying to read a std::vector from a tree I have made.
The usual CollectionProxy error, generate a dictionary comes back to me when trying to read the tree.
I am using a Makefile and compiling+linking against root.
After getting this to work using the commonly suggested gROOT->ProcessLine(".L loader.C+") way I was curious why I cannot get it to work in a “classic” c++ way.
First I tried what I remembered I did a while ago on root 5, using a LinkDef.h file, generating a dictionary. This did not work. Then, I stumbled across this post.
I have followed the root5 instructions but instead of loading the library as you would do in a macro I try to link with it. Still, I cannot read the tree.
My Makefile is attached. Can anyone advise me on this? Makefile.txt (853 Bytes)
I am not sure how the code looks like but I see two ways out:
Since you are in ROOT6, you add to the dictionary generation command these switches: -rml libMyLib.so -rmf libMyLib.rootmap . This will create an additional file, libMyLib.rootmap, which will be read by ROOT and will make the system able to load the library at the right time, i.e., in your case, when it’s time to read.
You directly load the library in your code before the reading part: upon load, the static initialisers, i.e. w/o any action from your side, in the dictionaries will inject into the ROOT type system the information necessary for reading.
On our hand, also given the number of posts you cite, we can consider to add vector to the root default set of dictionaries so to provide it “out of the box”.
Doing gROOT->ProcessLine(".L libMyLib.so") does not work… Only way I have this working so far is to
Where loader.C is just
#pragma link C++ class vector<TLorentzVector>+;
From what I understand, the Makefile I attached earlier should be ok no? I generate a dictionary for std::vector. I then create my own dynamic library with which I link against. Why is this not enough for root?
It would be useful I think if you can add that in the future as a default.
if the linkdef file is correct and the class selected, the dictionary is generated, compiled and linked into the library, the pcm file sits in the file system next to the shared library as well as a rootmap it is enough for root to perform I/O operations.
Maybe I am not understanding this well (I am new to this rootmap stuff).
The way I thought I was doing it was generating the dictionary, for which I had the dummy header a.h as from your example with a Linkdef is like follows.
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;
#pragma link C++ class std::vector<TLorentzVector>+;
Then, using the generated Dict.cpp file I would generate a dictionary and then link with it. How do I use the rml and rmf flags when libMyLib.so has not even been generated again? Do I need to run rootcling after I make the libMyLib.so?
I got the rootmap file generated, but the dictionary file had includes that couldn’t be found.
I have a directory structure with include/ and src/ folder (as you can see from my Makefile).
The Dict.cpp was being generated into src/ with an #include “include/a.h” for some reason.
If I made an include/a.h inside my src/ folder (where Dict.cpp) is everything works, but that is not “right”.
Another (easier and better) option is to just have Dict.cpp, Dict_rdict.pcm, libMyLib.so, libMyLib.rootmap generated to the base folder in which include/ lies in. This is easier because Dict_rdict.pcm has to be there anyways.***
However, something strange still happens - the libMyLib.rootmap has spaces infront of its name, something I have never seen before. I attached a screenshot, also my latest Makefile.
Thanks for the help, it is working now.
*** This is the correct way I agree, but I am still curious how to get rootcint to recognize these include folders I have, and to not write the Dict.cpp to #include “include/a.h” but just #include “a.h”. I realize the way these dictionaries are ment to work is that they should lie with the executable, but what happens if my folder structure is a little different? Anyways, that is not really the point of this thread. Makefile.txt (791 Bytes)
great that you could make this work!
About the headers not found: is this at runtime, dictionary generation time or at compile time?
About the rootmap file with spaces in front, this is really odd: do you have a command to reproduce it? Can you extract that from the makefile?
Sorry, I did not see this response until I went into the mailbox today.
The headers was at compile time. Dict.cpp was writing #include “include/a.h”. I guess I could add -I…/ my INCLUDEDIRS but I figured since I need Dict_rdict.pcm and the rootmap in my core directory (where src/ and include/ are located), where the executable is, I can just have Dict.cpp generated into there, and not into src/. It was not a real problem, just I think rootcling would automatically put include/a.h becuase that is what I indicated after my -c option (because that is the class it needs to select).
I think I might have had a space between -rml libMyLib.so in the Makefile, so it was putting it there? but that seems strange. However, now it is gone… and there is no more space so I really do not know the cause of that.
Thanks again with all the help on this and sorry for late reply. Everything works great!