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:
The object modules are not bound into the executable file by the linker during the compile-link sequence; such binding is deferred until runtime.
A shared library module is bound into system memory when the first running program references it. If any subsequent running program references it, that reference is mapped to this first copy.
Maintaining programs is easier with dynamic libraries. Installing an updated dynamic library on a system immediately affects all the applications that use it without requiring relinking of the executable.
Dynamic libraries introduce some additional tradeoff considerations:
Smaller a.out file
Deferring binding of the library routines until execution time means that the size of the executable file is less than the equivalent executable calling a static version of the library; the executable file does not contain the binaries for the library routines.
Possibly smaller process memory utilization
When several processes using the library are active simultaneously, only one copy of the memory resides in memory and is shared by all processes.
Possibly increased overhead
Additional processor time is needed to load and link-edit the library routines during runtime. Also, the library's position-independent coding might execute more slowly than the relocatable coding in a static library.
Possible overall system performance improvement
Reduced memory utilization due to library sharing should result in better overall system performance (reduced I/O access time from memory swapping).
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 (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.
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 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
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.
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
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.
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.
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.
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.