RE: Compiling vs loading library libEvent.so : USE the ROOT SCRIPTCOMPILER

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Wed Jan 26 2000 - 20:03:25 MET


Hi Philippe, and others

My previuos mail on thescript compiler has apparently stirred an
number of souls, so let me start out, and say: I _don't_ mind the
script compiler, but I think you shouldn't really on it for production
purposes. Below I answer to a number of observations made by Philippe
Canal, and will in the course of that, raise some general points on
making a ROOT based project, so please read on if this have our
intrest. 
 
From: "Philippe Canal" <pcanal@fnal.gov>

> Hi,
> 
> Just one more usefull feature of the script compiler is that it is
> totally machine independent.  The exact same .L foo.cc++ creates
> a shared on Linux, Osf1, sgi, etc... with any change and any maintenance
> of many complex makefiles.
> 
> Philippe.

Well, that's fine, but then again you could use tools like autoconf,
automake, libtool, etc. to find out which libraries, switches,
compilers, linkers, etc. to build with! Ofcourse, this is properly
only avaliable under Windoze using the Cygnus Bash - but hey, you
wouldn't use Windoze anyway, would you?

I guess you know this, but anyway: Some autmake, autoconf, libtool
stuff for ROOT is avaliable at 

      ftp.slac.stanford.edu:/users/langston/root/event-example-0.01.tar.gz

However, it doens't work if you used the "--prefix=<prefix>" option
for the configure script (as I've done). 

> You mentionned:
> 
> 	Why not just shift to your
> 	terminal, create a dynamicly loadable object:
> 
> 	  > g++ -fPIC -g -O2 -c foo.cc -o foo.o
> 	  > g++ -Wl,-soname,foo.so -o foo.so foo.o
> 
> 	shift back to ROOT, load the object
> 
>           root [1234] gSystem->Load("foo.so");
> 
> This technique does not make any of your symbols available to the
> cint interpreter.  So eventhough over compiled code would be able
> to access your functions or classes, you will not be able to create,
> or call them, directly from the root/cint prompt.
> 
> The missing step is calling rootcint:
> 
> 	rootcint -f fooDict.cc -c foo.h fooLinkDef.h
>
> In the fooLinkDef.h you have to list what you want to make availaible
> to cint. (and do not forget to compile and link those). 

I now that! I wasn't about to re-explain the way you compile things
for ROOT - that is well-documented actually. 

> In addition, the script compiler takes care of making sure you
> are compiling with the same options as the current root.  This
> is essential in most case to be able to load the shared library.

Hmm, not quite.  It's true for things like -I${ROOTSYS}/include,
etc. but what about "-fno-strength-reduce" or the "-j2" flag for Make?
Those doens't have to be the same. 

This actually goes to the question on what needs to be in the script
"root-config". I believe a minimal amount of data should be
output. That is, linker and compiler flags like "-rdynamic" shouldn't
be there. Actually, I believe it should only output relevant ROOT
paths, and libraries, nothing else. If you need to automate your make
procedure to other platforms, then your current, use something like
autoconf, automake, and libtool. They know far more then you coulkd
ever put into a simple script like "root-config" or any method of your
classes (unless you really want to make and IDE). 
  
> For example if root is compiled with --with-thread=-lpthread,
> at least on some platform, you HAVE TO compile you library with it.

Not the library, but you need to load "libpthread.so" in your ROOT
session (are you thinking of OSF1!, then use
"-Wl,-expect_unresolved,*". Otherwise, strange linker!).  

> In most case, I also prefer to have complete control of the make process.
> 
> However the script compiler provide you with a fast, low maintenance way
> of compiling small scripts and load them immediately.  (this way I do not
> have to write a makefile for every single test script I ever write).

This is not my intention either, and I agree that for such uses it
the script compiler shouldn't be deprecated. But then again, you may
find yourself writting macros to make your other macros - no, just
kidding! Actually, I keep a sort of skeleton file for makefiles. I
looks more or less like this (on my Debian GNU/Linux 2.1 box, using
ROOT 2.23.11, and EGCS 1.1.1):

      #!/usr/bin/make -f 
      TARGET_SO_NAME  = <fill in>
      TARGET_SO	      = lib$(TARGET_SO_NAME).so
      TARGET_SO_OBJS  = <fill in> $(TARGET_SO_NAME)Cint.o
      MAJOR           = <fill in>
      MINOR	      = <fill in>
      TARGET_EXE      = <fill in>
      TARGET_EXE_OBJS = $(TARGET_EXE:=.o)
      INCLUDES	      = <fill in>
      LIBS	      = <fill in> -L./ -l$(TARGET_SO_NAME)
      ROOTCINT	      = /usr/bin/rootcint
      CPPFLAGS	      = $(INCLUDES) $(shell root-config --cflags)
      CXX	      = g++
      CXXFLAGS	      = -g -O2 -fPIC -c
      LD	      = g++
      LDFLAGS	      = -Wl,-rpath,$(shell pwd) \
		        $(shell root-config --glibs) $(LIBS) -o
      SOFLAGS	      = -shared -Wl,-soname,
      LN	      = ln -sf
      %Cint.cc:%Inc.hh
		$(ROOTCINT) -f $@ -c $(INCLUDES) $< $*LinkDef.hh
      %.o:%.cc
		$(CXX) $(CPPFLAGS) $(CXXFLAGS) $@ $<
      %:%.o
		$(LD) $(LDFLAGS) $@ $^
      %.so:
		$(LD) $(SOFLAGS)$@.$(MAJOR) -o $@.$(MAJOR).$(MINOR) $^
		$(LN) $@.$(MAJOR).$(MINOR) $@.$(MAJOR)
		$(LN) $@.$(MAJOR) $@
      $(TARGET_SO):  $(TARGET_SO_OBJS)
      $(TARGET_EXE): $(TARGET_EXE_OBJS)

Notice the ".hh" - in that way Emacs knows right away it's C++, and
not C! The "-Wl,-rpath,$(shell pwd)" is ugly, but it's OK for
development. 
 
> In addition the Script Compiler let you customize the build process in
> the most obvious way (see TSystem::SetIncludePath and a few more explained
> in the documentation of TSystem::CompileMacro
> http://root.cern.ch/root/html/TSystem.html#TSystem:CompileMacro ).

Well, the last time build a Debian GNU/Linux package, it turned out
that the generated file "compiledata.h" wasn't generated properly, at
least not when you configured you ROOT sources with
"--prefix=<prefix>", which resulted in strange behaviour, and is now
corrected. The danger is that such oddities sneak in. (I recently
found a similar mistake for "system.rootrc" and "root-config", which
I've corrected in my newest ROOT 2.23.11 package for Debian GNU/Linux,
see earlier posting on roottalk.)
 
> So in summary the Script Compiler is the easy for those of us that prefer
> to avoid makefile when they can, to quickly compile and load a c++ files.

Why would you want to avoid Makefiles? I really like
Makefiles. Sometimes a make a Makefile file for creation of LaTeX
documents. Actually, I think you would find that 50% of my directories
contain a Makefile (I would be fun to do a "make" at top-level
wouldn't it!).  

Anyway, I don't think a script compiler is a bad idea. I'm just
concerned, that people stop doing proper libraries - after all, a
major advantage of C++ is code-reusing. Also, people _should_ get
thier hands dirty once in a while, if they really want to learn have
to do things properly. However, I've seen one too many times, people
interpreting slow macros, getting frustrated, and I guess a script
compiler would really help those people. But please don't make ROOT
into an IDE. 

Cheers, 

Christian Holm Christensen 
______________________________________________________________________
Address:                                     Phone:  (+45) 35 35 96 91 
  Sankt Hansgade 23, 1. th.                  Office: (+45) 353  25 307 
  DK-2200 Copenhagen N                       Web:    www.nbi.dk/~cholm    
  Denmark                                    Email:       cholm@nbi.dk



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:17 MET