I have one namespace (a la TMath) and one class I’d like to generate documentation for using THtml. I load the library containing these classes and the dictionary and do
THtml a
a.MakeAll()
after setting the environment to point at the source directory. I find that the main html page for my class says all the methods are inline, which they are not, and provides no documentation on them. I’m finding that the “source file” links point to files named with the cxx.html extension, but contain only the code from the header file. What is really perplexing is that in the case of the namespace, I only have a header file - there is no separate source file!
Neither the namespace nor the object inherit from TObject, so I don’t have a static Class() method to ask THtml::GetImplFileName(TClass*) to see what is happening. Is there a good way to figure out what I did wrong?
your classes don’t have to derive from TObject. But they have to have a ClassDef and ClassImp macro call, or THtml doesn’t know their source file names. You can also set them by hand, using the strongly discouraged, ugly TClass::SetImplFileName() interface (it’s really a hack we introduced for exactly this - and it’s ugly because it stores the const char* you pass, i.e. the original string has to stay in memory, unchanged, for this to work). As soon as gROOT->GetClass(“MyClass”)->GetImplFileName() returns something sensible, THtml should be able to find your sources.
Namespaces are not really supported as a separate entity - so also they get a source link, even though it just points to the header where the first occurrence of that namespace was seen.
Thanks for the tip on ClassDef/ClassImp. I also see now the NamespaceImp in TMath and tried use that for my TAstro namespace. However, when I try to load my shared library, I get
dlopen error: /usr/lib/libcosmocpp.so: undefined symbol: _ZN6TAstro4ROOT20GenerateInitInstanceEv
Load Error: Failed to load Dynamic link library /usr/lib/libcosmocpp.so
*** Interpreter error recovered ***
It is there. In fact, before adding the ClassDef/ClassImp/NamespaceImp macros, I was able to load the library. Now, I can only load the library if I don’t use the NamespaceImp.
One note is that my TAstro.cc is empty save for the include file and the NamespaceImp. It will eventually get filled in with some new functions , but I inline the currently implemented functions in the .hh. I don’t know if this matters or not.
Yes, I do have that in my dictionary. Here are the results of nm on my library and the compiled dictionary object. It seems to agree with the error reported by ROOT - it’s undefined. I don’t know the proper way to define it.
nm lib/.libs/libcosmocpp.so | grep GenerateInit | grep TAstro
0000b378 V _ZGVZN6TAstro4ROOT20GenerateInitInstanceEvE8instance
U _ZN6TAstro4ROOT20GenerateInitInstanceEv
0000b380 V _ZZN6TAstro4ROOT20GenerateInitInstanceEvE8instance
nm lib/cosmocppCint.o | grep GenerateInit | grep TAstro
00000000 V _ZGVZN6TAstro4ROOT20GenerateInitInstanceEvE8instance
00000000 V _ZZN6TAstro4ROOT20GenerateInitInstanceEvE8instance
Comparing the latter to TMath.o, I see:
nm ~/BUILDROOT/root_v5.11.06.cmr.1_i686_beta/root-5.11.06/base/src/G__Base2.o | grep GenerateInit | grep TMath
00000000 V _ZGVZN5TMath4ROOT20GenerateInitInstanceEvE8instance
00000000 W _ZN5TMath4ROOT20GenerateInitInstanceEv
00000000 V _ZZN5TMath4ROOT20GenerateInitInstanceEvE8instance
And there is the ‘W’ a weak symbol. I wonder how I get that!?
The weak symbol comes from the fact that for namespaces the GenerateInitInstance is defined ‘inline’ because you can create a dictionary for the same namespace several times.
The #pragma link C++ namespace TAstro;
should have add the inlined GenerateInitInstance to your dictionary. This is odd Can you check whether it is there or not?
right, let me re-phrase my useless question, so it becomes more useful
Do you have a
namespace TAstro {
namespace ROOT {
...
inline ::ROOT::TGenericClassInfo *GenerateInitInstance() {...}
static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstance(); R__UseDummy(_R__UNIQUE_(Init));
...
}
}in your dictionary? If so, could you attach the dictionary and tell us the compiler command you use to compile this file? That allows us to check why the symbol gets lost. If it’s not in there, then the Linkdef.h with the pragma link namespace doesn’t match the dictionary. Can you remove it, and have it re-generated? If the problem persists we’d need the Linkdef.h and the dictionary.