pragma link question

From: R. Eastman (eastman@tapestry.llnl.gov)
Date: Wed Jul 15 1998 - 23:56:42 MEST


Salutations,

I'm a little confused about how the "link" pragmas work and what they
are doing. The motivation for my asking is that I would like to be
able to pass the existing source through rootcint and have it generate
interface stubs for the extern's and classes they contain, so that the
variables are visible to the parser, without having to write a
seperate "pragma link" statement for each class, variable,...

Below are five small files of a simple little test code: Main.C,
TestClass.h, TestClass.C, and LinkDef.h. The LinkDef.h file uses the statement
	#pragma link off all globals
etc, which should turn off generation of interface stubs, and it then
then lists each variable, class, etc for which an interface should be created:
	#pragma link C++ global gX 
This works. My understanding, however, from looking at the file
UTILS_rootcint.cxx and also the documentation on makecint, is that by
default an interface stub will be created for all global symbols and
defined classes, which would be equivalent to
	#pragma link C++ all classes
etc. However, when I do this, I get 

> rootcint -f MyDict.C -c TestClass.h LinkDef.h
> Note: operator new() masked 1c
> Note: operator delete() masked 1c
> class TMemberInspector in /usr/home/rge/Root/root.v1.03/include/TMemberInspector.h line 26 original base of virtual func
> class TObject in /usr/home/rge/Root/root.v1.03/include/TObject.h line 67 original base of virtual func
> class TIterator in /usr/home/rge/Root/root.v1.03/include/TIterator.h line 25 original base of virtual func
> class TIter in /usr/home/rge/Root/root.v1.03/include/TCollection.h line 108 original base of virtual func
> class TString in /usr/home/rge/Root/root.v1.03/include/TString.h line 148 original base of virtual func
> class TObjLink in /usr/home/rge/Root/root.v1.03/include/TList.h line 86 original base of virtual func
> class TDatime in /usr/home/rge/Root/root.v1.03/include/TDatime.h line 22 original base of virtual func
> class TestClass1 in TestClass.h line 11 original base of virtual func
> Warning: Link requested for undefined class TClass  FILE: LINE:0
> Warning: Link requested for undefined class ofstream  FILE: LINE:0
> Warning: Link requested for undefined class TBrowser  FILE: LINE:0
> Warning: Link requested for undefined class TObjArray  FILE: LINE:0
> Warning: Link requested for undefined class TMethod  FILE: LINE:0
> Warning: Link requested for undefined class TMap  FILE: LINE:0
.
.
.

And it doesn't compile:

> g++ -g -Wall -fPIC -I/usr/home/rge/Root/root.v1.03/include   -c MyDict.C -o MyDict.o
> MyDict.C: In function `int G___va_start_1_0(struct G__value *, char *, struct G__par
> am *, int)':
> MyDict.C:6008: non-lvalue in assignment
> MyDict.C: In function `void G__cpp_setup_globalMyDict(...)':
> MyDict.C:8634: non-lvalue in unary `&'
> MyDict.C:8635: non-lvalue in unary `&'
> MyDict.C:8636: non-lvalue in unary `&'

The last three errors refer to these three lines in MyDict.C:
   G__memvar_setup((void*)(&stdout),69,0,0,-1,-1,-1,1,"stdout=",0,(char*)NULL);
   G__memvar_setup((void*)(&stderr),69,0,0,-1,-1,-1,1,"stderr=",0,(char*)NULL);
   G__memvar_setup((void*)(&stdin),69,0,0,-1,-1,-1,1,"stdin=",0,(char*)NULL);

I've tried turning off default generation of stubs for classes and
leaving it on for functions and globals, and turning if off for both
functions and classes, and if I leave off the LinkDef.h file
completely, I get

> rootcint -f MyDict.C -c TestClass.h
> Note: operator new() masked 1c
> Note: operator delete() masked 1c
> Warning: Link requested for undefined class TestClass  FILE: LINE:0
> g++ -g -Wall -fPIC -I/usr/home/rge/Root/root.v1.03/include   -c MyDict.C -o MyDict.o
> Linking myroot ...
> g++ -g Main.o TestClass.o MyDict.o -L/usr/X11/lib -L/usr/home/rge/Root/root.v1.03/li
> b -lNew -lBase -lCint -lClib -lCont -lFunc -lGraf -lGraf3d -lHist -lHtml -lMatrix -l
> Meta -lMinuit -lNet -lPostscript -lProof -lRint -lTree -lUnix -lZip -lGpad -lGX11 -l
> Motif -lWidgets -lX3d -ldl -lXm -lXt -lX11 -lm -rdynamic -o myroot
> TestClass.o: In function `TestClass1::Dictionary(void)':
> /usr/home/rge/Root/root.v1.03/MyTests4/TestClass.C:12: undefined reference to `TestClass1::DeclFileLine(void)'
> /usr/home/rge/Root/root.v1.03/MyTests4/TestClass.C:12: undefined reference to `TestClass1::DeclFileName(void)'
> /usr/home/rge/Root/root.v1.03/MyTests4/TestClass.C:12: undefined reference to `TestClass1::Class_Version(void)'
> TestClass.o: In function `__TestClass1Init__::__TestClass1Init__(void)':
> /usr/home/rge/Root/root.v1.03/MyTests4/TestClass.C:12: undefined reference to `TestClass1::Class_Version(void)'
> make: *** [myroot] Error 1

This, strangely, is a different behavior from when LinkDef.h says
	#pragma link all classes
which I would have assumed would really be equivalent.
So, what am I doing wrong?

Cheers
Ron Eastman

Lawrence Livermore National Laboratory
L-041
7000 East Avenue, PO Box 808, Livermore California 94551
001-925-423-7340
reastman@llnl.gov

 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

// ------------------- Main.C ----------------------
#include "TROOT.h"
#include "TRint.h"

extern void  InitGui();  // initializer for GUI needed for interactive interface
VoidFuncPtr_t initfuncs[] = { InitGui, 0 };

double gX;

// Initialize the ROOT system
TROOT root("Rint","The ROOT Interactive Interface", initfuncs);

int main(int argc, char **argv)
{
  gX = 3.0;

  // Create interactive interface
   TRint *theApp = new TRint("ROOT batch example", &argc, argv, NULL, 0);

   // Run interactive interface
   theApp->Run(kTRUE);

   printf("main: the value of gX is now %f\n", gX); 

    return(0);
}
//--------------------------------------------------

// ----------------- TestClass.h -------------
#ifndef _TestClass_included_
#define _TestClass_included_
#include <math.h>
#include "Rtypes.h" // needed for ClassDef() macro

void gFunc(float p); // define a function

extern double gX; // an external variable

class TestClass1 { // and a class
public:
  TestClass1(){}; // a constructor
  void Dummy(); // will print something profound
  int ijk; // an int
  ClassDef(TestClass1,1)
};

#endif

//--------------------- TestClass.C ---------------------
#include <stdio.h>
//*KEEP,TestClass.
#include "TestClass.h"
//*KEND.

void gFunc(float p){
printf("gFunc: the value of p is %f\n", p);
return;
}

ClassImp(TestClass1)

void TestClass1::Dummy()
{
  printf("hi there.\n");
  return;
}

// ---------------------- Makefile ----------------------

#---------------------------------------------------
#SHELL=/bin/sh
CXXFLAGS      = -g -Wall -fPIC -I$(ROOTSYS)/include
LDFLAGS       = -g
LD            = g++
DllSuf        = so
SOFLAGS       = -Wl,-soname, -shared

OPENGL=/usr/local
ROOTGLIBS     = -lGpad -lGX11 -lMotif -lWidgets -lX3d
ROOTLIBS      = -L$(ROOTSYS)/lib -lNew -lBase -lCint -lClib -lCont -lFunc \
	-lGraf -lGraf3d -lHist -lHtml -lMatrix -lMeta -lMinuit -lNet \
	-lPostscript -lProof -lRint -lTree -lUnix -lZip

GLIBS = $(OPENGL)/lib/*.so
LIBS          = -L/usr/X11/lib $(ROOTLIBS) $(ROOTGLIBS) -ldl -lXm -lXt -lX11 -lm -rdynamic
# -lPW

HDRS          = TestClass.h LinkDef.h

SRCS          = Main.C TestClass.C

OBJS          = Main.o TestClass.o MyDict.o

PROGRAM       = myroot

all:            $(PROGRAM)

$(PROGRAM):     $(OBJS)
	@echo "Linking $(PROGRAM) ..."
	$(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
	@echo "done"

clean:;         @rm -f $(OBJS) core MyDict.* myroot

###

TestClass.o: TestClass.C  TestClass.h

MyDict.o: MyDict.C
MyDict.C: LinkDef.h TestClass.h
	@ echo "Generating dictionary ..."
	test -f MyDict.C && /bin/rm MyDict.C ; \
	test -f MyDict.h && /bin/rm MyDict.h ; \
	rootcint -f MyDict.C -c TestClass.h LinkDef.h
#---------------------------------------------------

// ------------- LinkDef.h which works -----------------
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class TestClass1;
#pragma link C global gX;
#pragma link C++ function gFunc;
#endif



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:35 MET