Dynamic linking (shared libraries).


COMIS supports dynamic compilation and linking on HP-UX, SUN/OS/Solaris, ALPHA/OSF, Linux, IBM/RT and IRIX systems. Everywhere a COMIS filename file.f is given (in CALL, Fun/Plot, Ntuple/plot, etc...) the COMIS interpreter is invoked. To compile (instead of interpret) the code the following conventions have been introduced: (here shown with the CALL command)


 PAW > call file.f       | code is interpreted (default)
 PAW > call file.f77     | compilation of file.f with f77 and dynamic linking
 PAW > call file.c       | same with the C compiler
 
file.c should have the following form:

 #include <stdio.h>
 file_(int *i)
 {
    int j=*i*100;
    printf("this is a test %d\n",j);
 }
 
Note the _ added at the end of the procedure name. Then to call it from PAW it is enough to do:

 PAW > call file.c(123)
 this is a test 12300
 PAW > 
 

It is possible to load shared objects without executing the code. The following macro gives an example:


                               Macro comp
                               appl comis quit
                               !file filename.f77
                               quit
 

in this case the local compiler is invoked to process filename.f (note that the file extension remains .f even if the file is called with the extension .f77). Before invoking the compiler, COMIS perform preliminary operations:

  1. fills a list of used variables for ntuple watched common blocks,
  2. replaces VECTOR's name by Q(link(i)+offs),
  3. replaces calls to watched routines (CALL HFILL(...)) by call jumpcn(jmp(line),[-]line,...)

then COMIS creates and executes a script file to invoke the native fortran compiler and linker to create a shared object and load the shared object.

C code can also be loaded as shared objects. The following macro gives an example:


                               Macro comp
                               appl comis quit
                               !file filename.c
                               quit
 

in this case COMIS creates and executes a script file to invoke the native C compiler and linker to create a shared object and load the shared object.

It is also possible to load an existing shared library. In that case the local compiler is not invoked. There is two types of shared libraries:

  1. shared libraries produced from fortran code (invoked with extension .sl),
  2. shared libraries produced from C code (invoked with extension .csl).

The following macro shows how to load a shared library produced from fortran code:


                               Macro load
                               appl comis quit
                               !file filename.sl
                               quit
 

in this case COMIS analyse the file filename.f to fill a list of used variables for ntuple watched common blocks, and then load the shared object filename.sl.

The following macro shows how to load a shared library produced from C code:

                               Macro load
                               appl comis quit
                               !file filename.csl
                               quit
 

in this case COMIS doesn't analyse the source file, it only load the shared object filename.sl . This can be a way to use fortran features not supported by COMIS such as DOUBLE COMPLEX.

Note that when a procedure has been is loaded with one of the methods described above, it can then be accessed by its name only i.e. the file extension is not needed anymore providing the procedure's code has not changed.

To produce and load the shared library, COMIS produced a temporary script file which looks like this:

#! /bin/sh
 olddir=`pwd`
 cd CHPATH
 /bin/rm -f name.sl
 # for C compiler
 #    cc -c .... name.c
 CHCC name.c
 #for f77 compiler
 #    f77 -c .... name.f
 CHF77 name.f
 errno=$?'
 if [ $errno != 0 ]
 then
    exit $errno
 fi
 #for HPUX.
 ld -b -o name.sl name.o
 #for SUN.
 #    ld -G -o name.sl name.o     for Solaris
 ld -o name.sl name.o
 #for SGI.
 ld -shared -o name.sl name.o
 #for LINUX.
 ld -shared -o name.sl name.o
 #
 errno=$?
 if [ $errno != 0 ]
 then
   exit $errno
 fi
 /bin/chmod 555 name.sl
 /bin/rm -f name.o
 cd $olddir
 exit 0
 

This default script can be customised using COMIS directives.

The user can redefine CHPATH - The new directory where shared object and temporary files will be located (default is /tmp/),

                               Macro SetPath
                               appl comis quit
                               !setopt 'string' path
                               quit
 

The user can redefine CHF77 - fortran compiler directive:

                               Macro Setf77Options
                               appl comis quit
                               !setopt 'string' f77
                               quit

The user can redefine CHCC - C compiler directive:

                               Macro SetCOptions
                               appl comis quit
                               !setopt 'string' cc
                               quit
 

To have the current values of the !setopt parameters use:

                               Macro ShowOptions
                               appl comis quit
                               !setopt
                               quit
 

Default CHF77 value (fortran options)

Default CHCC value (C options)

HPUX f77 -c +z +ppu -K -O (before PAW 2.10)
f77 -c +z +ppu
cc -c +z -O (before PAW 2.10)
cc -c +z
SGI f77 -c -pic cc -c -pic
SUN f77 -c cc -cckr -c
IBM/RT xlf -qextname -qrndsngl -qcharlen=32767 -c cc -c
LINUX g77 -c cc -c
ALPHA/OSF f77 -c cc -c

Restrictions:

  1. Suppose you load/call a file which contains the f1 routine and then try load/call another file with the f2 routine which calls f1. It does not work on IBMRT. You will get error:
                         ERROR: Undefined symbol: .f1_
     
    To solve this problem you could add f1 routine into file with f2 routine.

  2. The list of the CERNLIB routines (and COMMON blocks) callable from a COMIS is given in the help of the command FORTRAN/CALL. Only the routines given in that list can be called from an interpreted COMIS program. Nevertheless, it is possible to call other routines present in the PAW module from a compiled COMIS program but this feature is strongly machine dependent:

    On UNIX, to check if the routine you want to call or the common block you want to access is used in the PAW module just do:
                         $ nm /cern/pro/bin/pawX11 | grep -i routine_name
     
    If nothing is returned it means that routine_name cannot be accessed.

  3. On Linux the function name should not contains the character "_".

  4. On all platforms when the routine name has no parameter, it is better to put empty parenthesis at the end of the routine name. On some platforms it is mandatory:
                               REAL FUNCTION select()
     

Note:

We recommend to also have a look at this page.


Release NotesKnown bugsFAQsContributionsTutorialReference manualDown loadMiscellaneous

Paw.Support@cern.ch