Autoloading unexpected feature

Dear all,

I am trying to port a project from root5 to root6. It consists of a set of libraries based on ROOT with some classes having a root dictionary. The compilation is made through cmake.
It compiles with both root5 and root6 but the behaviour regarding the autoloading features is different while it should be the same if I look at the libEvent example in the test directory.
Here is what I got with ROOT 6.02/02 , macosx64, Yosemite:

[code]root [0] Gw::BaseNucleus b
ROOT_prompt_0:1:5: error: no member named ‘BaseNucleus’ in namespace 'Gw’
Gw::BaseNucleus b

root [1] gSystem->Load("libGWCORE")
(int) 1
root [2] #include "BaseNucleus.h"
root [3] Gw::BaseNucleus b
(Gw::BaseNucleus &) @0x10f698060[/code]

It looks like BaseNucleus is not known while however the library containing this class is auto-loaded after the first command ?
by including the header file it works but this should be the case if I understood correctly for any class 
without the need to include the root dictionary.

I've a similar feature with ROOT 6.03/01 on linuxx8664gcc [unbuntu]

Starting from a new root session, just typing Gw [namespace for my project] I got Gw in color [recognized ?] or
[code]root [0] .class Gw
A Namespace declaration was found for Gw
[/code]

but still it does not recognised Gw::BaseNucleus ...
Here is a snapshot of the directory containing the libraries [included in DYLD_LIBRARY_PATH]

   566 janv. 26 13:13 libGWCORE_rdict.pcm
   932 janv. 26 13:13 libGWCORE.rootmap
1600576 janv. 26 13:13 libGWCORE.so

and a partial view of the root map file

[code]more lib/libGWCORE.rootmap
{ decls }
namespace Gw {  }
namespace Gw { template <typename Data_T> class Data; }

[ libGWCORE.so ]
# List of selected classes
class Gw::BaseNucleus
class Gw::Data<Char_t>
...
header BaseNucleus.h
header Env.h
...
# List of selected namespaces
namespace Gw[/code]

Any help, ideas of what I've not done ???
Many thanks!

Olivier

Hi Olivier,

this is not the expected behaviour.
Are you sure that the rootmap is in the LD_LIBRARY_PATH ?
To help to converge on this item, I built an example based on your descriptions which works: do you see any difference with your setup?
code

namespace Gw{
class BaseNucleus{};
}

selection

<rootdict>
<class name="Gw::BaseNucleus" />
<rootdict>

Dictionary generation and library compilation

genreflex classes.h -s sel.xml --rootmap al.rootmap;g++ -shared -fPIC classes_rflx.cpp `root-config --cflags --libs` -o libclasses.so

Root prompt

root [0] Gw::BaseNucleus a
(Gw::BaseNucleus &) @0x107e1b018

Hi and thank you for the answer !

Following your suggestion

genreflex classes.h -s sel.xml --rootmap al.rootmap;g++ -shared -fPIC classes_rflx.cpp `root-config --cflags --libs` -o libclasses.so
Selected class -> Gw::BaseNucleus for ROOT: Gw::BaseNucleus
$ root
Warning in <TInterpreter::ReadRootmapFile>: class  Gw::BaseNucleus found in libclasses.so  is already in libGWCORE.so 
root [0] Gw::BaseNucleus b
ROOT_prompt_0:1:5: error: no member named 'BaseNucleus' in namespace 'Gw'
Gw::BaseNucleus b
~~~~^
root [1] .q
root

It proves the library is loaded and I confirm the DYLD_LIBRARY_PATH contains the path to the lib.
To make the test you proposed, I have just added G to the name of the class  and it works 

root [0] Gw::BaseNucleusG b
(Gw::BaseNucleusG &) @0x114802051
root [1] .q

As the library seems to be autoloaded [?], I’ve tried to check if it contains what is required for the dictionary
to work. Here are some related symboles in it …

strings lib/libGWCORE.so | grep BaseNucleus
21TInstrumentedIsAProxyIN2Gw11BaseNucleusEE
N2Gw11BaseNucleusE
Gw::BaseNucleus
/Users/ … /Soft/MyProjects/gw-Trunk/src/root/core/BaseNucleus.h
#include "/Users/ … /Soft/MyProjects/gw-Trunk/src/root/core/BaseNucleus.h"
BaseNucleus.h
/Users/ … /Soft/MyProjects/gw-Trunk/src/root/core/BaseNucleus.cpp

  • ! - in BaseNucleus::Set N != A - Z

It looks like what I can see for a typical root object I know … but probably more is required …

Cheers
Olivier

Hi Olivier,

good. This shows that something is not understood in the setup.
Could you get rid of the example we discussed and try to autoload your original library? This time, increase the debug level though: just boot root like this “ROOTDEBUG=1 root -b”

Cheers,
Danilo

Hi Danilo,

here is root running with the debug level 1

Just starting ROOT

ROOTDEBUG=1 root -b
Info in <TROOT::InitSystem>: running with gDebug = 1
dynpath = /Users/Shared/root6/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib::.:/Users/Shared/root6/lib:/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:
dynpath = /Users/Shared/root6/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib::.:/Users/Shared/root6/lib:/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:
TClass::GetClass: Header Parsing - The representation of HepMC::GenVertex was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting HepMC::GenVertex in the linkdef/selection file.
TClass::GetClass: Header Parsing - The representation of HepMC::GenParticle was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting HepMC::GenParticle in the linkdef/selection file.
TClass::GetClass: Header Parsing - The representation of HepMC::Flow was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting HepMC::Flow in the linkdef/selection file.
TClass::GetClass: Header Parsing - The representation of HepMC::GenEvent was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting HepMC::GenEvent in the linkdef/selection file.
dynpath = /Users/Shared/root6/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib:/Users/Shared/root6/lib:/Users/stezow/Soft/MyProjects/gw-Release/lib::.:/Users/Shared/root6/lib::/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:
   ------------------------------------------------------------
  | Welcome to ROOT 6.02/02                http://root.cern.ch |
  |                               (c) 1995-2014, The ROOT Team |
  | Built for macosx64                                         |
  | From tag v6-02-02, 26 November 2014                        |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
   ------------------------------------------------------------

Info in <TPluginManager::LoadHandlerMacros>: /Users/Shared/root6/etc/plugins/TVirtualStreamerInfo
Info in <TPluginManager::FindHandler>: found plugin for TStreamerInfo
Info in <TInterpreter::AutoParse>: Parsing full payload for TStreamerInfo
Info in <TInterpreter::Autoparse>: >>> RSS key TStreamerInfo - before 62.308 MB - after 62.460 MB - delta 0.152 MB
Info in <TInterpreter::Autoparse>: >>> VSIZE key TStreamerInfo - before 95.968 MB - after 95.968 MB - delta 0.000 MB
Info in <TInterpreter::AutoParse>: Parsing full payload for TVirtualStreamerInfo
Info in <TInterpreter::Autoparse>: >>> RSS key TVirtualStreamerInfo - before 62.476 MB - after 62.592 MB - delta 0.116 MB
Info in <TInterpreter::Autoparse>: >>> VSIZE key TVirtualStreamerInfo - before 95.968 MB - after 95.968 MB - delta 0.000 MB
Info in <TMacOSXSystem::Load>: loaded library /Users/Shared/root6/lib/libMathCore.so, status 0

Trying to load the GWCORE library

root [0] gSystem->Load("libGWCORE")
Info in <TMacOSXSystem::Load>: loaded library /Users/stezow/Soft/MyProjects/gw-Release/lib/libGWCORE.so, status 0
(int) 0
root [1] Gw::BaseNucleus a
ROOT_prompt_1:1:5: error: no member named 'BaseNucleus' in namespace 'Gw'
Gw::BaseNucleus a
~~~~^

trying to type directly without loading the library

root [0] GInfo in <TMacOSXSystem::Load>: loaded library /Users/stezow/Soft/MyProjects/gw-Release/lib/libGWADFE.so, status 0
Info in <TInterpreter::TCling::AutoLoad>: loaded library libGWADFE.so for Gw
Gw::BaseNucleus b
ROOT_prompt_0:1:5: error: no member named 'BaseNucleus' in namespace 'Gw'
Gw::BaseNucleus b
~~~~^
root [1] 

Cheers,
Olivier

Hi Olivier,

thanks for the report.
The ROOT6 system incorporates a real compiler, clang. In order to be able to use the class at the prompt, it is necessary to make known to ROOT the location of the header where it is defined.
In order to do that, you can use the variable ROOT_INCLUDE_PATH, which works exactly as the well known LD_LIBRARY_PATH: just fill it with the paths where the includes are located, separated by “:”.

Cheers,
Danilo

Hi Danilo,

It does not help to set a ROOT_INCLUDE_PATH:

echo $ROOT_INCLUDE_PATH 
/Users/stezow/Soft/MyProjects/gw-Release/include/gw
gw-Release stezow$ ls /Users/stezow/Soft/MyProjects/gw-Release/include/gw/BaseNucleus.h 
/Users/stezow/Soft/MyProjects/gw-Release/include/gw/BaseNucleus.h
lyomatnuc02:gw-Release stezow$ root
root [0] gSystem->Getenv("ROOT_INCLUDE_PATH")
(const char *) "/Users/stezow/Soft/MyProjects/gw-Release/include/gw"
root [1] Gw::BaseNucleus b
ROOT_prompt_1:1:5: error: no member named 'BaseNucleus' in namespace 'Gw'
Gw::BaseNucleus b
~~~~^
root [2] 

Indeed, even before, without having the variable ROOT_INCLUDE_PATH defined, just typing
#include "BaseNucleus.h"
gives the possibility to declare on the prompt a Gw::BaseNucleus. But this is a normal cling feature as far as
I can understand. It proves however that root is able to find itself, I assume through the loaded library ?,
the path to the include file and then load it and then re-creates [?] a dictionary …

It may look like root is aware of some aspects in auto-loading things but at this end the dictionary
supposed to be in the lib/rootmap/rdict_pcm is not extracted …

Cheers
Olivier

Hi Olivier,

could you please:
o give me a recipe to reproduce this issue with GammaWare?
o Type this at the prompt: TClass::GetClass(“Gw::BaseNucleus”)

Cheers,
Danilo

Hi Danilo,

here is some snapshot playing a bit with TClass::GetClass(“Gw::BaseNucleus”)

root
  | Welcome to ROOT 6.02/02                http://root.cern.ch |
  | Built for macosx64                                         |
  | From tag v6-02-02, 26 November 2014                        |

root [0] TClass *c = TClass::GetClass("Gw::BaseNucleus")
(class TClass *) 0x7fb1c281f340
root [1] Gw::BaseNucleus b
ROOT_prompt_1:1:5: error: no member named 'BaseNucleus' in namespace 'Gw'
Gw::BaseNucleus b
~~~~^
root [2] c->GetDataMember("fA")
(class TDataMember *) 0x7fb1c2d36a70
root [3] 

I’ve joined a gip/tar file [Normally on svn but I cannot commit yet]
Unzip the tar file. The procedure is with cmake.

mkdir gw-Release; cd gw-Release
cmake -DCMAKE_INSTALL_PREFIX=$PWD -Dcxx11=ON ../gw-Trunk/
make install
source Gw-env.sh

I hope it is going to work as I am still working on the package …

Many thanks !
Olivier
gw.tar.gz (1.51 MB)

Hi,

I understood the issue, which is twofold and concerns the way in which you generate the dictionaries.

  1. You are generating the dictionaries using the option “-writeEmptyRootPCM” : try without using this option.
    This option assumes that the headers of your classes are part of the pch and forces rootcling to generate simplified dictionaries.
  2. The command to generate, for example, the core dictionary should look like:
cd /Users/aaa/GW/gw-Release/src/root/core && rootcling -f G__GWCORE.cxx -s /Users/aaa/GW/gw-Release/lib_/libGWCORE.so -rml libGWCORE.so -rmf /Users/aaa/GW/gw-Release/lib_/libGWCORE.rootmap -c -Iinc -I/Users/aaa/GW/gw-Trunk/src/root/core -I/Users/aaa/GW/gw-Release/include -I/Users/aaa/RootDevel/Root6/head/buildNinja/include /Users/aaa/GW/gw-Release/include/GwConfig.h BaseNucleus.h Data.h Env.h GammaTracker.h InfoData.h Measure.h PadManager.h RandObj.h Random.h LinkDef.h

i.e. the header files should be listed relative to the include paths you specify.

These two changes were enough to have the examples discussed today working.

Cheers,
Danilo

Hi Danilo,

I saw this option in the root package itself and, as I am dealing with modules with/without dictionary,
I though it was an option to avoid error of rootling in case there were no real dictionary to generate.

Apparently a wrong guess …

Now it works fro all the modules in the package … MANY thanks !

Cheers,
Olivier

Hi Olivier,

don’t worry: I imagined you saw libCore in root and transposed the arguments to libGWCore :slight_smile:
Do not hesitate to ask for help/advice if you encounter any other issue during the migration to ROOT6.

Danilo