Problem with compiled function library


I’m trying to create a library with functions and classes, some of which use ROOT classes, but are not derived from ROOT classes. I would like to compile these classes and functions prior to using ROOT to make passing them to other users a little easier.

I’ve created a simple example which has a function called foo which simply prints “Hello World” to stdout.


The above seems to load the library, but when I run the code it does not print “Hello World” to stdout. To get this far I had to create a libFoo.rootmap file to let it know libFoo contained a function called foo, though I am not sure I got the rootmap syntax correct.

To run the code I use

root -c foo_test.C -q

If I remove the .rootmap file I get an error that says foo is declared, but is not defined.

Also, I’m not sure if I need to create dictionary files for classes which are not derived from ROOT classes. At any rate the behavior seems to be the same if I do not create and use the dictionary files.

I’ve attached the small example.

Any help is appreciated.

Best regards,
test.tar.gz (750 Bytes)

in your “fooLinkDef.h” file, change:


See also:

BTW. The “clean” target in your “makefile” should also remove “foo_dict.h”, not only “foo_dict.C”.

I am stupid. No?
Pepe Le Pew.

It works!

I knew there was something very basic I was missing.

Thank you very much.


I was struggling with almost exactly the same problem and I found this thread on the topic. However, once I tried adding the line:

#pragma link C++ function foo;
The problem didn’t get solved.
I quickly realised that my testing script is not unnamed like the one in the example provided by “terrydoherty”,
and this seems to be the difference. Normally, I like to compile my scripts just like they were normal C++ programs. So, I created a testing named script, pretty much similar to the one in the example, called foo_test2.C :

#include <TSystem.h> #include "foo.h" void foo_test2() { gSystem->Load(""); foo(); }
The piece of code compiles with no problems, but as soon as I try to execute it with root:

root -q foo_test2.C root [0] Processing foo_test2.C... Error: foo() declared but not defined foo_test2.C:8: *** Interpreter error recovered ***
I get the error again.
This doesn’t happen with the unnamed script foo_test.C:

root -q foo_test.C root [0] Processing foo_test.C... Hello World
And now the disturbing part:
If I comment the line number 2 in foo_test2.C, and I leave the code like this:

#include <TSystem.h> // #include "foo.h" void foo_test2() { gSystem->Load(""); foo(); }
The program works perfectly:

root -q foo_test2.C root [0] Processing foo_test2.C... Hello World
But the macro doesn’t compile since the compiler doesn’t know the definition of the function foo().
Don’t you find this strange? This is actually a problem for me because I don’t know how to compile my macros (to make them work faster in a precompiled program) and make them work with CINT at the same time.
Any help is appreciated. I have modified the original example by Terry Doherty to include the not working cases.
test.2.tar.gz (4.12 KB)
Best regards,


[quote]But the macro doesn’t compile since the compiler doesn’t know the definition of the function foo().
Don’t you find this strange? [/quote]This is somewhat the expected behavior.

The fact that the interpreter is confused by the presence of the #include “foo.h” is somewhat unexpected (it is a bug), however you can easily work around it with:#include <TSystem.h> #ifndef __CINT__ #include "foo.h" #endif void foo_test2() { gSystem->Load(""); foo(); }

However compile this code does not make a lot of sense unless you also update it as:#include <TSystem.h> #ifndef __CINT__ #include "foo.h" #endif void foo_test2() { #ifdef __CINT__ gSystem->Load(""); #endif foo(); }as the original code might compile properly but will not link and/or load properly unless you explicitly load libFoo before loading the compiled version of test2 (the loading of the library will failed to the missing symbol for foo).


Thanks, Philippe!
I forgot the #ifdef / #ifndef CINT trick.
That’s enough to make the macros compatible in both CINT and precompiled modes.