Problem with Shared libraries(?) and Cygwin

G’day,

  I'm seeing something strange when compiling in Cygwin that I don't see with Linux.   I see this with both root 4.02 and root 5.08.

 In the attached tar.gz file, 

I first go to the HighLevelObjects directory and make a shared library (‘make’). This just makes an object ‘evt’ and compiles it and its dictionary to a shared library.

I then go to fakeTuple, make it and run it (make; ./fakeTuple.exe). This makes a root file with one ‘evt’ per event stored in a TClonesArray for 10 events.

Finally, I go to topAnaExample make and run it (make; ./topAnaExample.exe). This should just print out the run and event numbers.

For hooking up the tclonesarray, I do:

   // evt
   TClonesArray *evtTcaPtr = new TClonesArray("evt", 1);
   chainPtr->GetBranch("evt")->SetAutoDelete(false);
   chainPtr->SetBranchAddress("evt", &evtTcaPtr);
   branchNameVec.push_back("evt");

When this happens, I get

Error in <TClonesArray::TClonesArray>: evt is not a valid class name
Warning in <TClass::TClass>: no dictionary for class evt is available

and the code crashes as it tries to access this branch.

If, instead, I ask it to hook the same thing up again

   TClonesArray *evtTcaPtr = new TClonesArray("evt", 1);
   chainPtr->GetBranch("evt")->SetAutoDelete(false);
   chainPtr->SetBranchAddress("evt", &evtTcaPtr);
   branchNameVec.push_back("evt");

   evtTcaPtr = new TClonesArray("evt", 1);
   chainPtr->GetBranch("evt")->SetAutoDelete(false);
   chainPtr->SetBranchAddress("evt", &evtTcaPtr);
   branchNameVec.push_back("evt");

I get the same warning messages from the first time I hooked up ‘evt’, but no error messages from the second time and it successfully reads out the evt.

If I have two or more objects, it complains about the first one, but not any subsequent classes.

If I load the shared library into root interactive (gSystem->Load("…/shlib/libHighLevelObjects");), it doesn’t complain when I then load the file (i.e. it doesn’t tell me that there is no dictionary for ‘evt’ class).

I do not get any error messages when running on linux (kai and root 3.X and gcc and root 4.x).

I’m assuming I’m doing something stupid in one of my makefiles, but I can’t see what it is.

Cheers,
Charles

p.s. As I said, this happens in 4.02 and 5.08. In 5.08, you have to comment out the following line in topAnaExample.cc. What are we supposed to use instead in root5?

   TAuthenticate::SetGlobalUser("cdfdata");

p.s. I seem to be having problems attaching the .tar.gz file so:
www-cdf.fnal.gov/~cplager/broken.tar.gz
broken.tar.gz (31.5 KB)

Hi Charles,

before I take a look at your code tomorrow - could you check that the dictionary is the same for cygwin and linux, for the same root version? (Check with diff, please - you might have to run dos2unix.)

And please check that your dll exports the dictionary symbols properly. Could you do gSystem->Load("…/shlib/libHighLevelObjects"); .class evt and post the output?

Thanks, that saves me some time :slight_smile:

Cheers, Axel.

[quote=“Axel”]Hi Charles,

before I take a look at your code tomorrow - could you check that the dictionary is the same for cygwin and linux, for the same root version? (Check with diff, please - you might have to run dos2unix.)
[/quote]

I can’t seem to get either 4.02 or 5.08 on linux (I have 4.00.08, but ls tells me that the files are quite different). I will try and install 4.00.08 on cygwin and then run the comparison.

root [1] gSystem->Load("../shlib/libHighLevelObjects")
(int)0

root [2] .class evt
===========================================================================
class evt
 size=0x78 FILE:/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll LINE:-1
 (tagnum=1341,voffset=-1,isabstract=0,parent=-1,gcomp=0:-1,d21=~cd=75)
List of base class--------------------------------------------------------
0x0        public: TObject //Basic ROOT object
List of member variable---------------------------------------------------
Defined in evt
(compiled)          0xb        int runNumber
(compiled)          0xf        int eventNumber
(compiled)          0x13       int runSection
(compiled)          0x17       int CosmicOOTLow
(compiled)          0x1b       int bunchNum159
(compiled)          0x1f       int bunchNum36
(compiled)          0x27       double gliveInstLumi
(compiled)          0x2f       double gliveTotalLumi
(compiled)          0x37       double instLumi
(compiled)          0x3f       double totalLumi
(compiled)          0x47       double scalerInstLumi
(compiled)          0x4f       double scalerTotalLumi
(compiled)          0x57       double bunchInstLumi
(compiled)          0x5f       double gliveBunchInstLumi
(compiled)          0x67       double bunchTotalInstLumi //should compare to instLumi
(compiled)          0x6f       time_t creationTime
(compiled)          0x0        private: static TClass* fgIsA
List of member function---------------------------------------------------
filename       line:size busy function type and name  (in evt)
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: void ~evt(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: evt evt(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static TClass* Class(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static const char* Class_Name(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static Version_t Class_Version(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static void Dictionary(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: virtual TClass* IsA(void) const;
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: virtual void ShowMembers(TMemberInspector& insp,char* parent);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: virtual void Streamer(TBuffer& b);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: void StreamerNVirtual(TBuffer& b);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static const char* DeclFileName(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static int ImplFileLine(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static const char* ImplFileName(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: static int DeclFileLine(void);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: evt evt(const evt&);
/mount/cplagerdoc/junk/bla4/HighLevelObjects/./../shlib/libHighLevelObjects.dll  -1:-1   0 public: evt& operator=(const evt&);

Thanks,
Charles

On your website, you don’t have 4.00.08 (it’s 4.00.06). So I tried 4.00.06. In any case, the dictionary files are of different sizes (listed as linux 4.00.08, cygwin 4.08 and cygwin 4.00.06):

-rw-r--r--    1 cplager  cdf         31505 Mar 30 15:49 dict_HighLevelObjects.C
-rw-r--r--    1 cplager  cdf         27513 Mar 30 15:53 dict_HighLevelObjects.C_cygwin
-rw-r--r--    1 cplager  cdf         24750 Mar 30 16:08 dict_HighLevelObjects.C_cygwin_cygwin_4.00.06
-rw-r--r--    1 cplager  cdf          2169 Mar 30 15:49 dict_HighLevelObjects.h
-rw-r--r--    1 cplager  cdf          1906 Mar 30 15:53 dict_HighLevelObjects.h_cygwin
-rw-r--r--    1 cplager  cdf          1387 Mar 30 16:08 dict_HighLevelObjects.h_cygwin_cygwin_4.00.06

The numbers of lines are different as well

cplager@b0pcucla09> wc *.C*
    681    1917   31505 dict_HighLevelObjects.C
    654    1782   27513 dict_HighLevelObjects.C_cygwin
    606    1640   24750 dict_HighLevelObjects.C_cygwin_cygwin_4.00.06
   1941    5339   83768 total
cplager@b0pcucla09> wc *.h*
     49     119    2169 dict_HighLevelObjects.h
     48     134    1906 dict_HighLevelObjects.h_cygwin
     40      92    1387 dict_HighLevelObjects.h_cygwin_cygwin_4.00.06
    137     345    5462 total

Do you want me to upload the files (or put them on a website somewhere)?

Thanks,
Charles

Hi Charles,

argh, I cannot even generate dictionaries for your classes - due to this stupid cygwin rootcint problem. So you’ll have to post all your dictionaries somewhere, and even then all I might find out is that it’s a problem with the dll loading. Which I already suspect to be the problem for rootcint. But we can give it a try, if you refuse to accept that win32gcc is doomed :slight_smile:

Cheers, Axel.

[quote=“Axel”]Hi Charles,

argh, I cannot even generate dictionaries for your classes - due to this stupid cygwin rootcint problem. So you’ll have to post all your dictionaries somewhere, and even then all I might find out is that it’s a problem with the dll loading. Which I already suspect to be the problem for rootcint.
[/quote]

When you use go to ‘HighLevelObject’ and type ‘make’, that does successfully create dictionary files (they are in the ‘object’ subdirectory) in my version of cygwin.

You can find all files here:
www-cdf.fnal.gov/~cplager/broken/

Give up soft links (and the rest of posix)? Never. :smiley:

Hi Charles,

I had to add a “-I.” when compiling the dicts. Even with that it won’t work - your dictionaries do not contain the ROOT part but only the cint part. You should have seen a linker error, and you should not have been able to build a library.

Try to re-generate the dictionaries. If that doesn’t help, generate them on linux, and try with those. That should fix it - and if it does you’ve discovered yet another problem with rootcint on cygwin.

Cheers, Axel.

Hi Axel,

[quote=“Axel”]
I had to add a “-I.” when compiling the dicts. Even with that it won’t work - your dictionaries do not contain the ROOT part but only the cint part. You should have seen a linker error, and you should not have been able to build a library.

Try to re-generate the dictionaries. If that doesn’t help, generate them on linux, and try with those. That should fix it - and if it does you’ve discovered yet another problem with rootcint on cygwin.

Cheers, Axel.[/quote]

O.k. I’m not understanding something I should be. When I go to the ‘HighLevelObjects’ directory and type ‘make’ It seems to successfully create the dictionary files, compile them (the relavant lines from the Makefile below, links to entire makefile and the output at the end).

objects/dict_%.o: include/%.hh dict/%_linkdef.h
	@echo "Generating dictionary for $< $@"
	$(ROOTSYS)/bin/rootcint -f $(patsubst %.o, %.C, $@) -c -Idict -Iinclude -I../include $(notdir $^) 
	$(CXX) -c $(CXXFLAGS) -I. -o $@ $(patsubst %.o, %.C, $@)

It doesn’t seem to make any difference if I add ‘-I.’ to the compilation line in the makefile or not. It always compiles and links fine and then when I try and run, it complains

Error in <TClonesArray::TClonesArray>: evt is not a valid class name
Warning in <TClass::TClass>: no dictionary for class evt is available

Everytime I compile from ‘clean’, it remakes and recompiles the dictionaries (so it isn’t that I just screwed the dictionary generation up once, I’m apparently doing it repeatly :slight_smile: ) Is there something wrong with how I am telling it to generate and compile the dictionaries?

But I can’t be completely screwing up the dictionaries and the resulting shared library because when I load it into root and then load in the root file, it doesn’t complain about no dictionaries for evt. Are there different options for making a dll for linking against as opposed to loading into root?

The last issue is that I don’t have access to the same version of root on cygwin and linux (I can’t get access to anything newer than 4.00.08 on linux). Would a 4.00.08 dictionary work on Cygwin 4.02?

Thank you for all of the time and effort you have spent on this,
   Charles

Makefile:
www-cdf.fnal.gov/~cplager/broken … s/Makefile

HighLevelObject make output:
www-cdf.fnal.gov/~cplager/broken/hlo_make.html

Tarfile including dictionaries, .o files and dlls (compiled with cygwin root 4.02):
www-cdf.fnal.gov/~cplager/broken/broken.tar.gz

All files (in case you don’t want to grab the tar file)
www-cdf.fnal.gov/~cplager/broken/

Hi,
sorry - I was trying to build your dll with its dict (generated with an old root) by linking against my new root. That won’t work.

So instead I tried to build root v4.02 from sources. That doesn’t work with the current gcc, because it neeeds different options than what we had back at 4.02.

So now we’ll have to use some version < v5.10 - for both root and dictionaries. v5.10 won’t work as win32gcc’s rootcint is wrecked. I’ll try v5.08, but I’ll have to rebuild from (carefully patched i.e. ni some parts updated) sources, as the binary distrib doesn’t work with the current cygwin environment. So I’m building root now - more news tomorrow.

Cheers, Axel.

Hi,

with 5.08 fakeTuple coredumps. I’ll be on vacation the next week, and I won’t have time to fix this tomorrow. Sorry… Next update around the 18th.

Axel.

Hi Charles,

bad news. I cannot run any of your code with the GCC I have, due to this bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24196. All I can do is wait until the known fix is put into libstdc++'s CVS, and a fixed GCC is distributed. Any fix we’ll find for your problem won’t help your users without a fixed libstdc++ anyway.

Cheers, Axel.

Hi Charles,

as requested by you by email I re-tested it with gcc 3.4.4-2. It works! You’ll have to make a few changes to your Makefile, though:

ROOTLIBS=$(shell root-config --glibs) -lRootAuth FCNCLIBS= -L$(LIBDIR) -Wl,-u,_G__cpp_setupdict_HighLevelObjects -lHighLevelObjects LIBS = $(FCNCLIBS) $(ROOTLIBS)

should do it. You need -lRootAuth for TAuthenticate::SetGlobalUser, you need to switch the order of root’s libs and yours, and you should explicitely request the dictionary init routine to be linked in.

Cheers, Axel.

Hi Axel,

 Great!  Thanks for the help.  Just a request for clarification:
-Wl,-u,_G__cpp_setupdict_HighLevelObjects 

With Root4, we didn’t need these lines. Shouldn’t this happen automatically? And if I want to add another class OtherClass, do I just

-Wl,-u,_G__cpp_setupdict_OtherClass 

to the line?

Cheers,
Charles

Hi Charles,

[quote=“cplager”]-Wl,-u,_G__cpp_setupdict_HighLevelObjects With Root4, we didn’t need these lines. Shouldn’t this happen automatically? [/quote]It should. Worth a try :slight_smile:

[quote=“cplager”]And if I want to add another class OtherClass, do I just-Wl,-u,_G__cpp_setupdict_OtherClass to the line?[/quote]No, it’s only one for the whole dictionary - as long as both classes are included in the same dictionary you only need to pass that one main dictionary symbol.

Cheers, Axel.