Sun Studio 12: Fortran Programming Guide

4.5 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:

4.5.1 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.

4.5.2 Position-Independent Code and –xcode

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 the -xcode compiler option.

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.

Use the compiler flag -xcode=v for specifying the code address space of a binary object. With this 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 the legacy -pic flag, and -xcode=pic32 is equivalent to -PIC.)

The -xcode=pic32 compiler option is similar to -xcode=pic13, but allows the global offset table to span the range of 32–bit addresses. See the f95(1) man page or the Fortran User’s Guide, for details.

4.5.3 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:

f95 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 Solaris operating environments. 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:

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

Here the user’s libabc.a and libxyz.a file are linked (rather than or, 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:

f95 -m64 -o cdf -nolib cdf.o -Bstatic -lsunmath \ -Bdynamic -lm -lc

4.5.4 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, could be referenced by the compiler option -lmyfavs.

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

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

4.5.5 A Simple Dynamic Library

Building a dynamic library requires a compilation of the source files with the -xcode 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% f95 -o -G -xcode=pic13 -ztext  \ 
– *.f

–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% f95 -o trylib -R”pwd” trylib.f
demo% file trylib
trylib:ELF 32–bit MSB executable SPARC Version 1, dynamically linked, not stripped
demo% ldd trylib => /export/home/U/Tests/ => /opt/SUNWspro/lib/ => /opt/SUNWspro/lib/ => /usr/lib/

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.

4.5.6 Initializing Common Blocks

When building dynamic libraries, insure proper initialization of common blocks (by DATA or BLOCK DATA) by gathering the initialized common blocks into the same library, and referencing that library before all others.

For example:

demo% f95 -G -xcode=pic32 -o blkdat1.f blkdat2.f blkdat3.f
demo% f95 -o prog main.f

The first compilation creates a dynamic library from files that define common blocks and initialize them in BLOCK DATA units. The second compilation creates the executable binary, linking the compiled main program with the dynamic libraries required by the application. Note that the dynamic library that initializes all the common blocks appears first before all the other libraries. This insures the blocks are properly initialized.