Dear Jiri Thank you very much for your offer, I have now created a testcode which demonstrates the problems. Below you can find all files including the make files: gmake -f Makefile4MyClassA gmake -f Makefile4MyClassB gmake -f Makefile4Mygui I include also a macro which shows that the libraries work within root: .x macroMyClass.C When I delete all code using libMyClassB and link Mygui only with libMyClassA, then the Mygui can be compiled but running it gives the error: ./Mygui: error in loading shared libraries: ./Mygui: undefined symbol: __8MyClassA However, when I link both libraries, I get the link error: Mygui.o: In function `TMyFrame::FRun1(void)': Mygui.o(.text+0xc58): undefined reference to `MyClassA::MyClassA(void)' ./libMyClassB.so: undefined reference to `operator>>(TBuffer &, MyClassA *&)' collect2: ld returned 1 exit status It seems that my make file may be incorrect? Thank you very much for your help Best regards Christian //////////////////////////////////// //--------- MyClassA.h ------------- #ifndef MYCLASSA #define MYCLASSA ////////////////////////////////////////////////////////////////////////// // MyClassA // ////////////////////////////////////////////////////////////////////////// #include "TObject.h" #include "TString.h" class MyClassA : public TObject { private: TString fString; public: MyClassA(); virtual ~MyClassA(); virtual void FTest(const char *vName); ClassDef(MyClassA,1) //MyClassA }; #endif //--------- MyClassA.cxx ------------- #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include "MyClassA.h" ClassImp(MyClassA); MyClassA::MyClassA() { } MyClassA::~MyClassA() { } void MyClassA::FTest(const char *vName) { fString = vName; cout << " MyClassA: fDir = " << vName << endl; } //--------- MyClassALinkDef.h ------------- #ifdef __CINT__ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class MyClassA+; #endif //--------- Makefile4MyClassA ------------- # Makefile for class MyClassA. # shell: gmake -f Makefile4MyClassA ARCH = linuxppcegcs CXX = ObjSuf = o SrcSuf = cxx ExeSuf = DllSuf = so OutPutOpt = -o ROOTCFLAGS := $(shell root-config --cflags) ROOTLIBS := $(shell root-config --libs) ROOTGLIBS := $(shell root-config --glibs) ifeq ($(ARCH),linuxegcs) # Linux with egcs (>= RedHat 5.2) CXX = g++ CXXFLAGS = -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared endif ifeq ($(ARCH),linuxppcegcs) # MkLinux with egcs/glibc CXX = g++ CXXFLAGS = -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared -Wl,-soname, endif CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) $(SYSLIBS) GLIBS = $(ROOTGLIBS) $(SYSLIBS) #------------------------------------------------------------------------------ MYCLASSAO = MyClassA.$(ObjSuf) MyClassADict.$(ObjSuf) MYCLASSAS = MyClassA.$(SrcSuf) MyClassADict.$(SrcSuf) MYCLASSASO = libMyClassA.$(DllSuf) OBJS = $(MYCLASSAO) PROGRAMS = $(MYCLASSASO) #------------------------------------------------------------------------------ .SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf) all: $(PROGRAMS) $(MYCLASSASO): $(MYCLASSAO) $(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ clean: @rm -f $(OBJS) core .SUFFIXES: .$(SrcSuf) ### MyClassA.$(ObjSuf): MyClassA.h MyClassADict.$(SrcSuf): MyClassA.h MyClassALinkDef.h @echo "Generating dictionary MyClassADict..." @rootcint -f MyClassADict.$(SrcSuf) -c MyClassA.h MyClassALinkDef.h .$(SrcSuf).$(ObjSuf): $(CXX) $(CXXFLAGS) -c $< //////////////////////////////////// //--------- MyClassB.h ------------- #ifndef MYCLASSB #define MYCLASSB ////////////////////////////////////////////////////////////////////////// // MyClassB // ////////////////////////////////////////////////////////////////////////// #include "TObject.h" #include "TString.h" #include "MyClassA.h" class MyClassA; class MyClassB : public TObject { private: MyClassA *fClassA; TString fString; public: MyClassB(); virtual ~MyClassB(); virtual void FTest(const char *vName); virtual void FTestA(const char *vName); ClassDef(MyClassB,1) //MyClassB }; #endif //--------- MyClassB.cxx ------------- #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include "MyClassB.h" ClassImp(MyClassB); MyClassB::MyClassB() { fClassA = new MyClassA(); } MyClassB::~MyClassB() { delete fClassA; } void MyClassB::FTest(const char *vName) { fString = vName; cout << " MyClassB: fDir = " << vName << endl; } void MyClassB::FTestA(const char *vName) { fString = vName; fClassA->FTest(vName); cout << " MyClassB: fDir = " << vName << endl; } //--------- MyClassBLinkDef.h ------------- #ifdef __CINT__ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class MyClassB+; #endif //--------- Makefile4MyClassB ------------- # Makefile for class MyClassB. # shell: gmake -f Makefile4MyClassB ARCH = linuxppcegcs CXX = ObjSuf = o SrcSuf = cxx ExeSuf = DllSuf = so OutPutOpt = -o ROOTCFLAGS := $(shell root-config --cflags) ROOTLIBS := $(shell root-config --libs) ROOTGLIBS := $(shell root-config --glibs) ifeq ($(ARCH),linuxegcs) # Linux with egcs (>= RedHat 5.2) CXX = g++ CXXFLAGS = -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared endif ifeq ($(ARCH),linuxppcegcs) # MkLinux with egcs/glibc CXX = g++ CXXFLAGS = -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared -Wl,-soname, endif CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) $(SYSLIBS) GLIBS = $(ROOTGLIBS) $(SYSLIBS) #------------------------------------------------------------------------------ MYCLASSBO = MyClassB.$(ObjSuf) MyClassBDict.$(ObjSuf) MYCLASSBS = MyClassB.$(SrcSuf) MyClassBDict.$(SrcSuf) MYCLASSBSO = libMyClassB.$(DllSuf) OBJS = $(MYCLASSBO) PROGRAMS = $(MYCLASSBSO) #------------------------------------------------------------------------------ .SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf) all: $(PROGRAMS) $(MYCLASSBSO): $(MYCLASSBO) $(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ clean: @rm -f $(OBJS) core .SUFFIXES: .$(SrcSuf) ### MyClassB.$(ObjSuf): MyClassB.h MyClassBDict.$(SrcSuf): MyClassB.h MyClassBLinkDef.h @echo "Generating dictionary MyClassBDict..." @rootcint -f MyClassBDict.$(SrcSuf) -c MyClassB.h MyClassBLinkDef.h .$(SrcSuf).$(ObjSuf): $(CXX) $(CXXFLAGS) -c $< ///////////////////////////////// //--------- Mygui.h ------------- #ifndef __MYGUI__ #define __MYGUI__ #include "RQ_OBJECT.h" #include "TGFrame.h" #include "TRootEmbeddedCanvas.h" #include "TGMenu.h" #include "TGLayout.h" #include "TGTextEntry.h" #include "TGTextBuffer.h" #include "TGListBox.h" #include "TGFileDialog.h" #include "TString.h" #include "MyClassA.h" #include "MyClassB.h" /* // Constants const Int_t kBufSize = 256; const char *kSep = "="; const char *kPathSep = "/"; const char *kSepPt = "."; */ class MyClassA; class MyClassB; ////////////////////////////////////////////////////////////////////////// // TMyFrame // ////////////////////////////////////////////////////////////////////////// class TMyFrame { RQ_OBJECT() private: TGMainFrame *fMain; TGCompositeFrame *fFrame; TRootEmbeddedCanvas *fCanvas; TGMenuBar *fMenuBar; TGPopupMenu *fMenuFile; TGLayoutHints *fL1, *fL2, *fL3, *fL4, *fL5; TList *fCleanup; Bool_t fHasProject; // Parameters MyClassA *fClassA; MyClassB *fClassB; TString fDir; public: TMyFrame(const TGWindow *vWindow, UInt_t vWidth, UInt_t vHeight); virtual ~TMyFrame(); void FRun1(); void FRun2(); // Slots void FCloseWindow(); void FHandleMenu(Int_t vId); ClassDef(TMyFrame,0) //MainFrame }; #endif //--------- Mygui.cxx ------------- #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <fstream.h> #include "TROOT.h" #include "TApplication.h" #include "TVirtualX.h" #include "Mygui.h" // Constants const Int_t kBufSize = 256; const char *kSep = "="; const char *kPathSep = "/"; const char *kSepPt = "."; // TMyFrame enum ECommandIds { M_FILE, M_FILE_RUN1, M_FILE_RUN2, M_FILE_EXIT, }; ClassImp(TMyFrame); //----------------------------------------------------------------------// // TMyFrame //----------------------------------------------------------------------// TMyFrame::TMyFrame(const TGWindow *vWindow, UInt_t vWidth, UInt_t vHeight) { fHasProject = kFALSE; fCleanup = new TList; // Create main frame. A TGMainFrame is a top level window. fMain = new TGMainFrame(vWindow, vWidth, vHeight); fMain->Connect("CloseWindow()", "TMyFrame", this, "FCloseWindow()"); // Create menubar and popup menus. fL1 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0); fL2 = new TGLayoutHints(kLHintsTop | kLHintsRight); fL3 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1); fL4 = new TGLayoutHints(kLHintsLeft | kLHintsTop); fL5 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5); fCleanup->Add(fL1); fCleanup->Add(fL2); fCleanup->Add(fL3); fCleanup->Add(fL4); fCleanup->Add(fL5); // File menu fMenuFile = new TGPopupMenu(gClient->GetRoot()); fMenuFile->AddEntry("&Run1", M_FILE_RUN1); fMenuFile->AddEntry("&Run2", M_FILE_RUN2); fMenuFile->AddEntry("E&xit", M_FILE_EXIT); // Connect menus to FHandleMenu method fMenuFile->Connect("Activated(Int_t)","TMyFrame",this,"FHandleMenu(Int_t)"); // Add menus to MenuBar fMenuBar = new TGMenuBar(fMain, 1, 1, kHorizontalFrame); fMenuBar->AddPopup("&File", fMenuFile, fL1); // fDir = gSystem->WorkingDirectory(); fDir = "/home/christian/dir"; fMain->AddFrame(fMenuBar, fL3); // Frame for Canvas fFrame = new TGCompositeFrame(fMain, 200, 20, kVerticalFrame); fMain->AddFrame(fFrame, fL4); fCanvas = new TRootEmbeddedCanvas("canvasA",fFrame,300,200); fFrame->AddFrame(fCanvas, fL5); fMain->SetWindowName("MyFrame"); fMain->MapSubwindows(); fMain->Resize(fMain->GetDefaultSize()); fMain->SetWMPosition(140,120); fMain->MapWindow(); }//Constructor //----------------------------------------------------------------------// TMyFrame::~TMyFrame() { fCleanup->Delete(); delete fCleanup; delete fMenuBar; delete fMenuFile; delete fCanvas; delete fFrame; delete fMain; }//Destructor //----------------------------------------------------------------------// void TMyFrame::FRun1() { printf("FRun1-------------------------------\n"); cout << " Directory: " << fDir << endl; fClassA = new MyClassA(); fClassA->FTest(fDir); delete fClassA; }//FRun //----------------------------------------------------------------------// void TMyFrame::FRun2() { printf("FRun2-------------------------------\n"); cout << " Directory: " << fDir << endl; fClassB = new MyClassB(); fClassB->FTest(fDir); fClassB->FTestA(fDir); delete fClassB; }//FRun //----------------------------------------------------------------------// void TMyFrame::FCloseWindow() { // delete this; //does not exit root gApplication->Terminate(0); //exit root, needed for standalone App }//FCloseWindow //----------------------------------------------------------------------// void TMyFrame::FHandleMenu(Int_t vId) { switch (vId) { // File menu case M_FILE_RUN1: this->FRun1(); break; case M_FILE_RUN2: this->FRun2(); break; case M_FILE_EXIT: this->FCloseWindow(); break; default: printf("Menu item %d selected\n", vId); break; } }//FHandleMenu //---- Main program ----------------------------------------------------// TROOT root("Mygui", "GUI for test"); int main(int argc, char **argv) { TApplication theApp("App", &argc, argv); if (gROOT->IsBatch()) { fprintf(stderr, "%s: Cannot run in batch mode\n", argv[0]); return 1; } new TMyFrame(gClient->GetRoot(), 400, 220); theApp.Run(); return 0; } //--------- MyguiLinkDef.h ------------- #ifdef __CINT__ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class TMyFrame; #endif //--------- Makefile4Mygui ------------- # Makefile for Mygui. # modified from root example Event # shell: gmake -f Makefile4Mygui ARCH = linuxppcegcs CXX = ObjSuf = o SrcSuf = cxx ExeSuf = DllSuf = so OutPutOpt = -o LPATH = . MYLIB = -L$(LPATH) -lMyClassB -lMyClassA #MYLIB = -L$(LPATH) -lMyClassA ROOTCFLAGS := $(shell root-config --cflags) ROOTLIBS := $(shell root-config --libs) ROOTGLIBS := $(shell root-config --glibs) ifeq ($(ARCH),linuxegcs) # Linux with egcs (>= RedHat 5.2) CXX = g++ CXXFLAGS = -I ./ -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared endif ifeq ($(ARCH),linuxppcegcs) # MkLinux with egcs/glibc CXX = g++ CXXFLAGS = -O -Wall -fPIC LD = g++ LDFLAGS = -O SOFLAGS = -shared endif CXXFLAGS += $(ROOTCFLAGS) LIBS = $(ROOTLIBS) $(SYSLIBS) GLIBS = $(ROOTGLIBS) $(SYSLIBS) #------------------------------------------------------------------------------ MYGUIO = Mygui.$(ObjSuf) MyguiDict.$(ObjSuf) MYGUIS = Mygui.$(SrcSuf) MyguiDict.$(SrcSuf) MYGUI = Mygui$(ExeSuf) OBJS = $(MYGUIO) PROGRAMS = $(MYGUI) #------------------------------------------------------------------------------ .SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf) all: $(PROGRAMS) $(MYGUI): $(MYGUIO) # $(LD) $(LDFLAGS) $(MYGUIO) $(MYLIB) $(GLIBS) $(OutPutOpt) $(MYGUI) $(LD) $(LDFLAGS) $(OutPutOpt) $(MYGUI) $(MYGUIO) $(MYLIB) $(GLIBS) # $(LD) $(LDFLAGS) $^ $(MYLIB) $(GLIBS) $(OutPutOpt)$@ @echo "$@ done" clean: @rm -f $(OBJS) core distclean: clean @rm -f $(PROGRAMS) $(MYGUIO) *Dict.* *.def *.exp \ *.root *.ps *.so .def so_locations # @rm -rf cxx_repository .SUFFIXES: .$(SrcSuf) ### Mygui.$(ObjSuf): Mygui.h MyguiDict.$(SrcSuf): Mygui.h MyguiLinkDef.h @echo "Generating dictionary $@..." @rootcint -f $@ -c $^ .$(SrcSuf).$(ObjSuf): $(CXX) $(CXXFLAGS) -c $< ///////////////////////////////// //--------- macroMyClass.C ------------- void macroMyClass() { gROOT->Reset(); gSystem->Load("/home/christian/rt/rootcode/xps/libMyClassA.so"); gSystem->Load("/home/christian/rt/rootcode/xps/libMyClassB.so"); MyClassA *vMyClassA = new MyClassA(); MyClassB *vMyClassB = new MyClassB(); vMyClassA->FTest("/home/TestNameAAA"); vMyClassB->FTest("/home/TestNameBBB"); vMyClassB->FTestA("/home/TestNameAAABBB"); delete vMyClassB; delete vMyClassA; }//macro Jiri Masik wrote: > Hi Christian, > > if you want send me your code+Makefile or all object files you are > willing to link. or put it on a web. I'll have a look. > > Jiri
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:58 MET