Fortran Programming Guide

Creating Dynamic Libraries

Dynamic library files are built by the linker ld from precompiled object modules that can be bound into the executable file after execution begins.

Another feature of a dynamic library is that modules can be used by other executing programs in the system without duplicating modules in each program's memory. For this reason, a dynamic library is also a shared library.

A dynamic library offers the following features:

Tradeoffs for Dynamic Libraries

Dynamic libraries introduce some additional tradeoff considerations:

Performance profiles among programs vary greatly from one to another. It is not always possible to determine or estimate in advance the performance improvement (or degradation) between dynamic versus static libraries. However, if both forms of a needed library are available to you, it would be worthwhile to evaluate the performance of your program with each.

Position-Independent Code and -pic

Position-independent code (PIC) can be bound to any address in a program without requiring relocation by the link editor. Such code is inherently sharable between simultaneous processes. Thus, if you are building a dynamic, shared library, you must compile the component routines to be position-independent (by using compiler options -pic or -PIC).

In position-independent code, each reference to a global item is compiled as a reference through a pointer into a global offset table. Each function call is compiled in a relative addressing mode through a procedure linkage table. The size of the global offset table is limited to 8 Kbytes on SPARC processors. The -PIC compiler option is similar to -pic, but -PIC allows the global offset table to span the range of 32-bit addresses.

Version 5.0 of f77 and version 2.0 of f90 introduce a more flexible compiler flag, -xcode=v, for specifying the code address space of a binary object. With this compiler flag, 32-, 44-, or 64-bit absolute addresses can be generated, as well as small and large model position-independent code. -xcode=pic13 is equivalent to -pic, and -xcode=pic32 is equivalent to -PIC. See the f77(1) and f90(1) man pages, or the Fortran User's Guide, for details.

Binding Options

You can specify dynamic or static library binding when you compile. These options are actually linker options, but they are recognized by the compiler and passed on to the linker.

-Bdynamic | -Bstatic

-Bdynamic sets the preference for shared, dynamic binding whenever possible. -Bstatic restricts binding to static libraries only.

When both static and dynamic versions of a library are available, use this option to toggle between preferences on the command line:

f77 prog.f -Bdynamic -lwells -Bstatic -lsurface

-dy | -dn

Allows or disallows dynamic linking for the entire executable. (This option may appear on the command line only once.)

-dy allows dynamic, shared libraries to be linked. -dn does not allow linking of dynamic libraries.

Binding in 64-Bit Environments

Some static system libraries, such as libm.a and libc.a, are not available on 64-bit environments with Solaris 7. These are supplied as dynamic libraries only. Use of -dn in these environments will result in an error indicating that some static system libraries are missing. Also, ending the compiler command line with -Bstatic will have the same effect.

To link with static versions of specific libraries, use a command line that looks something like:

f77 -o prog prog.f -Bstatic -labc -lxyz -Bdynamic

Here the user's libabc.a and libxyz.a file are linked (rather than libabc.so or libxyz.so), and the final -Bdynamic insures that the remaining libraries, including system libraries, and dynamically linked.

In more complicated situations, it may be necessary to explicitly reference each system and user library on the link step with the appropriate -Bstatic or -Bdynamic as required. First use LD_OPTIONS set to '-Dfiles' to obtain a listing of all the libraries needed. Then perform the link step with -nolib (to suppress automatic linking of system libraries) and explicit references to the libraries you need. For example:

f77 -xarch=v9 -o cdf -nolib cdf.o-Bstatic -lF77 -lM77 -lsunmath -Bdynamic -lm -lc

Naming Conventions

To conform to the dynamic library naming conventions assumed by the link loader and the compilers, assign names to the dynamic libraries that you create with the prefix lib and the suffix .so. For example, libmyfavs.so could be referenced by the compiler option -lmyfavs.

The linker also accepts an optional version number suffix: for example, libmyfavs.so.1 for version one of the library.

The compiler's -hname option records name as the name of the dynamic library being built.

A Simple Dynamic Library

Building a dynamic library requires a compilation of the source files with the -pic or -PIC option and linker options -G, -ztext, and -hname. These linker options are available through the compiler command line.

You can create a dynamic library with the same files used in the static library example.

Example: Compile with -pic and other linker options:


demo% f77 -o libtestlib.so.1 -G -pic -ztext -hlibtestlib.so.1 *.f
delte.f:
      delte:
      q_fixx:
dropx.f:
      dropx:
etc.f:
      q_fill:
      q_step:
      q_node:
      q_warn:
evalx.f:
      evalx:
linkz.f:
      linkz:
markx.f:
      markx:
point.f:
      point:
Linking:

-G tells the linker to build a dynamic library.

-ztext warns you if it finds anything other than position-independent code, such as relocatable text.

Example: Make an executable file a.out using the dynamic library:


demo% f77 -o trylib -R`pwd` trylib.f libtestlib.so.1 
trylib.f:
 MAIN main:
demo% file trylib
trylib:ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped
demo% ldd trylib
     libtestlib.so.1 => /export/home/U/Tests/libtestlib.so.1
     libF77.so.4 => /opt/SUNWspro/lib/libF77.so.4
     libc.so.1 => /usr/lib/libc.so.1
     libdl.so.1 => /usr/lib/libdl.so.1

Note that the example uses the -R option to bind into the executable the path (the current directory) to the dynamic library.

The file command shows that the executable is dynamically linked.

The ldd command shows that the executable, trylib, uses some shared libraries, including libtestlib.so.1; libf77, libdl, and libc are included by default by f77.