Libraries in CMT and Gaudi

Purpose

This page is an attempt to explain some of the basic concepts about libraries, libraries in CMT and Gaudi libraries in CMT.

Libraries in General

Libraries in CMT

Gaudi Libraries in CMT

Note: [ ... ] denote comments concerning simple things (like suffixes) that are system-dependant.

 

Libraries in General  (I'm talking about C++ libraries here, though I shan't keep writing that, cuz I'm lazy)

Conceptually, a library is a collection of object modules kept in a single file with some kind of directory structure so that the individual any particular module can be found. This is a convenience when linking: it is not necessary to enumerate the individual object modules needed to resolve references when linking; it suffices to include the library as input to the linker and the linker will find the modules it needs.

There are two kinds of library: static and shareable. When supplied as input to the linker, they are treated differently. When a static library is input to the linker, the procedure is roughly the following:

  1. The linker searches the directory to see which heretofore unresolved references in the entity it is linking can be resolved by objects in the library.
  2. These modules are copied to the output; references to them are adjusted accordingly

For a shareable library, however, there is an extra level of indirection. It could be something like this (I don't claim to describe any real linker, but this should be close to the behavior of the old DEC VMS linker)

  1. The linker searches the directory to see which heretofore unresolved references in the entity it is linking can be resolved by objects in the library (same as for static).
  2. The linker makes a sort of copy of the directory, which consists of a set of pairs
    module name offset from start of shareable
    but leaves a "blank" for the offset field.
  3. The linker partially resolves a reference to an object in the shareable by inserting the address of the blank location field in the (copied) directory entry.

Unlike the static library case, there is more to be done and this is perhaps the most important difference between shareable and static libraries: the loader has to finish the job of resolving references at run time. An invented loader to go with the invented linker above could "fix up" the blank directory entries by first finding the shareable at runtime and loading it into memory, keeping track of the address where it was loaded, then fill in the blank with a jump instruction whose target is the start of the shareable plus the offset for that object. The offset is read from the directory of the shareable loaded, not necessarily the same as the one that was linked against (though with this scheme there are some constraints on the directoriesof the link-time and run-time shareables)

Another difference between the two libraries is the information needed at link time. In the shareable case, the object modules themselves are not needed; only the directory.

Finally  the system must know where to look for shareable libraries that might be linked into your executable. This is done via environment variables, PATH for Windows and LD_LIBRARY_PATH for unix.

 

Libraries in CMT

General CMT info

The CMT philosophy is to divide code into packages, which contain classes that have some similar purpose.  It is therefore natural that one would compile these classes and link them into a library.  To create a library one uses the following command in the requirements file for the package

    library Particles proton.cxx electron.cxx muon.cxx

The above command creates a shareable library called Particles.dll [ libParticles.so on unix].  If you wish to create a static library use the -no_share flag

    library Particles -no_share proton.cxx electron.cxx muon.cxx

CMT understands how to build the library based on the above command.  But one also needs to specify how to link using this library.  For instance suppose we had another package, called Physics, that depended on the static version of the Particles library.  Assume the library Particles is in a package which is also called Particles.  In that case we would need to specify the linking options for the Particles package as follows

    macro Particles_linkopts  " ${PARTICLESROOT}/${DEBUGDIR}/libParticles.lib " 

CMT by default looks for a macro of the form <package>_linkopts in order to define the linking option for this package.  So in this case CMT knows that linking option for Particles is to simply include the static Particles library (Note: PARTICLESROOT is a predefined CMT macro which points to the base of the package, DEBUGDIR is the directory under the base where the binaries are installed).

Remember, however, that we use CMT to deal with the differences from platform to platform.  Therefore we should actually use a version of the above command that can deal with either unix or Windows environment.

    macro Particles_linkopts  " ${PARTICLESROOT}/${DEBUGDIR}/libParticles.a "
              VisualC                 " ${PARTICLESROOT}/${DEBUGDIR}/libParticles.lib "

The above command says that Particles_linkopts defaults to the unix version of the library, but uses the Windows version if we are on Windows (which is specified by the VisualC tag).

 

Libraries in Gaudi

General Gaudi info

Libraries in Gaudi add an additional level of complexity.  Gaudi distingusihes two types of libraries: linker libraries and component libraries.  These libraries are built and used in different fashions.

1) Linker Libraries - These are both static and shareable libraries that are used to link executables as described in the sections above.  Linker libraries export all their symbols and are needed during the link phase.  So if package A depends on package B, package A needs the package B library (be it a shareable or a static library) during the linking phase.

2) Component libraries - "[Component] libraries contain one or many software components implementing a number of abstract interfaces" - this description is right out of the Gaudi manual.  Component libraries have the following features

Writing a component library necesitates the following in-code features

A component also needs some specific definitions in the requirements file for the package it is in

    library ReconComp Recon/*.cpp Dll/*.cpp

    set ReconCompShr "${RECONCOMPROOT}/${DEBUGDIR}/libReconComp"

    private 

    macro ReconComp_shlibflags "$(componentshr_linkopts) $(use_linkopts)" \
               VisualC                       "$(componentshr_linkopts) $(use_linkopts) $(Win32Debug)"

Couple comments:

Finally one needs to explicitly load the component at run-time.  This can be done, for instance, in the jobOptions.txt file, by specifying

    ApplicationMgr.DLLs += { "ReconComp" };

 

A note on terminology: Gaudi chose to use the term "dll" in much of it s in-code reference to component libraries.  For instance, in the above command one makes reference to ApplicationMgr.DLLs

This is a somewhat confusing convention for two reason

  1. On Linux component libraries have a .so suffix, not a .dll suffix.
  2. On Windows, not all dll libraries are components.  Component libraries are a certain type of dll libraries (or a certain type of shareable, to be platform independant)

When describing Gaudi libraries, make sure to keep these subtleties in mind.


T. Lindner Last Modified: 2002-03-20 14:33:53 -0800