Contained WithinFind More DocumentationFeatured Support Resources | Download this book in PDF (392 KB)
Chapter 4 LibrariesThis chapter describes how to use and create libraries of subprograms. Both static and dynamic libraries are discussed. Understanding LibrariesA software library is usually a set of subprograms that have been previously compiled and organized into a single binary library file. Each member of the set is called a library element or module. The linker searches the library files, loading object modules referenced by the user program while building the executable binary program. See ld(1) and the Solaris Linker and Libraries Guide for details. There are two basic kinds of software libraries:
Typical system libraries that have both static (.a) and dynamic (.so) versions are:
There are two advantages to the use of libraries:
Library files provide an easy way for programs to share commonly used subroutines. You need only name the library when linking the program, and those library modules that resolve references in the program are linked and merged into the executable file. Specifying Linker Debugging OptionsSummary information about library usage and loading can be obtained by passing additional options to the linker through the LD_OPTIONS environment variable. The compiler calls the linker with these options (and others it requires) when generating object binary files. Using the compiler to call the linker is always recommended over calling the linker directly because many compiler options require specific linker options or library references, and linking without these could produce unpredictable results. demo% setenv LD_OPTIONS '-m -Dfiles' demo% f77 -o myprog myprog.f Example: Using LD_OPTIONS to create a load map: Some linker options do have compiler command-line equivalents that can appear directly on the f77 or f90 command. These include -Bx, -dx, -G, -hname, -Rpath, and -ztext. See the f77(1) and f90(1) man pages or the Fortran User's Guide for details. More detailed examples and explanations of linker options and environment variables can be found in the Solaris Linker and Libraries Guide. Generating a Load MapThe linker -m option generates a load map that displays library linking information. The routines linked during the building of the executable binary program are listed together with the libraries that they come from. Example: Using -m to generate a load map: demo% setenv LD_OPTIONS '-m'
demo% f77 any.f
any.f:
MAIN:
LINK EDITOR MEMORY MAP
output input virtual
section section address size
.interp 100d4 11
.interp 100d4 11 (null)
.hash 100e8 2e8
.hash 100e8 2e8 (null)
.dynsym 103d0 650
.dynsym 103d0 650 (null)
.dynstr 10a20 366
.dynstr 10a20 366 (null)
.text 10c90 1e70
.text 10c90 00 /opt/SUNWspro/SC5.0/lib/crti.o
.text 10c90 f4 /opt/SUNWspro/SC5.0/lib/crt1.o
.text 10d84 00 /opt/SUNWspro/SC5.0/lib/values-xi.o
.text 10d88 d20 sparse.o
...
Listing Other InformationAdditional linker debugging features are available through the linker's -Dkeyword option. A complete list can be displayed using -Dhelp. Example: List linker debugging aid options using the -Dhelp option: demo%
ld -Dhelp
...
debug: args display input argument processing
debug: bindings display symbol binding;
debug: detail provide more information
debug: entry display entrance criteria descriptors
...
demo%
For example, the -Dfiles linker option lists all the files and libraries referenced during the link process: demo% setenv LD_OPTIONS '-Dfiles'
demo% f77 direct.f
direct.f:
MAIN direct:
debug: file=/opt/SUNWspro/SC5.0/lib/crti.o [ ET_REL ]
debug: file=/opt/SUNWspro/SC5.0/lib/crt1.o [ ET_REL ]
debug: file=/opt/SUNWspro/SC5.0/lib/values-xi.o [ ET_REL ]
debug: file=direct.o [ ET_REL ]
debug: file=/opt/SUNWspro/SC5.0/lib/libM77.a [ archive ]
debug: file=/opt/SUNWspro/lib/libF77.so [ ET_DYN ]
debug: file=/opt/SUNWspro/SC5.0/lib/libsunmath.a [ archive ]
...
See the Linker and Libraries Guide for further information on these linker options. Consistent Compiling and LinkingEnsuring a consistent choice of compiling and linking options is critical whenever compilation and linking are done in separate steps. Compiling any part of a program with any of the following options requires linking with the same options: -a, -autopar, -Bx, -fast, -G, -Lpath, -lname,-mt, -nolib, -norunpath, -p, -pg, -xlibmopt, -xlic_lib=name, -xprofile=p Example: Compiling sbr.f with -a and smain.f without it, then linking in separate steps (-a invokes tcov old style profiling): demo% f77 -c -a sbr.f
demo% f77 -c smain.f
demo% f77 -a sbr.o smain.o {link step; pass -a to the linker}
Also, a number of options require that all source files be compiled with that option. These include: -autopar, -cg92, -dx, -dalign, -dbl, -explicitpar, -f, -misalign, -native, -parallel, -pentium, -PIC, -pic, -xarch=a, -xcache=c, -xchip=c, -xF, -xtarget=t, -ztext See the f77(1) and f90(1) man pages and the Fortran User's Guide for details on all compiler options. Setting Library Search Paths and OrderThe linker searches for libraries at several locations and in a certain prescribed order. Some of these locations are standard paths, while others depend on the compiler options -Rpath, -llibrary, and -Ldir and the environment variable LD_LIBRARY_PATH. Search Order for Standard Library PathsThe standard library search paths used by the linker are determined by the installation path, and they differ for static and dynamic loading. <install-point> is the path to where the Fortran compilers have been installed. In a standard install of the software this is /opt . Static LinkingWhile building the executable file, the static linker searches for any libraries in the following paths (among others), in the specified order:
These are the default paths used by the linker. Dynamic LinkingThe dynamic linker searches for shared libraries at runtime, in the specified order:
The search paths are built into the executable. LD_LIBRARY_PATH Environment VariableUse the LD_LIBRARY_PATH environment variable to specify directory paths that the linker should search for libraries specified with the -llibrary option. Multiple directories can be specified, separated by a colon. Typically, the LD_LIBRARY_PATH variable contains two lists of colon-separated directories separated by a semicolon: dirlist1;dirlist2 The directories in dirlist1 are searched first, followed by any explicit -Ldir directories specified on the command line, followed by dirlist2 and the standard directories. That is, if the compiler is called with any number of occurrences of -L, as in: f77 ... -Lpath1 ... -Lpathn ... then the search order is: dirlist1 path1 ... pathn dirlist2 standard_paths When the LD_LIBRARY_PATH variable contains only one colon-separated list of directories, it is interpreted as dirlist2. In the Solaris 7 operating environment, a similar environment variable, LD_LIBRARY_PATH_64 can be used to override LD_LIBRARY_PATH when searching for 64-bit dependencies. See the Solaris Linker and Libraries Guide and the ld(1) man page for details.
Library Search Path and Order--Static LinkingUse the -llibrary compiler option to name additional libraries for the linker to search when resolving external references. For example, the option -lmylib adds the library libmylib.so or libmylib.a to the search list. The linker looks in the standard directory paths to find the additional libmylib library. The -L option (and the LD_LIBRARY_PATH environment variable) creates a list of paths that tell the linker where to look for libraries outside the standard paths. Were libmylib.a in directory /home/proj/libs, then the option -L/home/proj/libs would tell the linker where to look when building the executable: demo% f77 -o pgram part1.o part2.o -L/home/proj/libs -lmylib Command-Line Order for -llibrary OptionsFor any particular unresolved reference, libraries are searched only once, and only for symbols that are undefined at that point in the search. If you list more than one library on the command line, then the libraries are searched in the order in which they are found on the command line. Place -llibrary options as follows:
Command-Line Order for -Ldir OptionsThe -Ldir option adds the dir directory path to the library search list. The linker searches for libraries first in any directories specified by the -L options and then in the standard directories. This option is useful only if it is placed preceding the -llibrary options to which it applies. Library Search Path and Order--Dynamic LinkingWith dynamic libraries, changing the library search path and order of loading differs from the static case. Actual linking takes place at runtime rather than build time. Specifying Dynamic Libraries at Build TimeWhen building the executable file, the linker records the paths to shared libraries in the executable itself. These search paths can be specified using the -Rpath option. This is in contrast to the -Ldir option which indicates at buildtime where to find the library specified by a -llibrary option, but does not record this path into the binary executable. The directory paths that were built in when the executable was created can be viewed using the dump command. Example: List the directory paths built into a.out: demo% f77 program.f -R/home/proj/libs -L/home/proj/libs -lmylib demo% dump -Lv a.out | grep RPATH [5] RPATH /home/proj/libs:/opt/SUNWspro/lib Specifying Dynamic Libraries at RuntimeAt runtime, the linker determines where to find the dynamic libraries that an executable needs from:
As noted earlier, use of LD_LIBRARY_PATH can have unexpected side-effects and is not recommended. Fixing Errors During Dynamic LinkingWhen the dynamic linker cannot locate a needed library, it issues this error message:
The message indicates that the libraries are not where they are supposed to be. Perhaps you specified paths to shared libraries when the executable was built, but the libraries have subsequently been moved. For example, you might have built a.out with your own dynamic libraries in /my/libs/, and then later moved the libraries to another directory. Use ldd to determine where the executable expects to find the libraries: demo% ldd a.out
libsolib.so => /export/home/proj/libsolib.so
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
If possible, move or copy the libraries into the proper directory or make a soft link to the directory (using ln -s) in the directory that the linker is searching. Or, it could be that LD_LIBRARY_PATH is not set correctly. Check that LD_LIBRARY_PATH includes the path to the needed libraries at runtime. Creating Static LibrariesStatic library files are built from precompiled object files (.o files) using the ar(1) utility. The linker extracts from the library any elements whose entry points are referenced within the program it is linking, such as a subprogram, entry name, or COMMON block initialized in a BLOCKDATA subprogram. These extracted elements (routines) are bound permanently into the a.out executable file generated by the linker. Tradeoffs for Static LibrariesThere are three main issues to keep in mind regarding static, as compared to dynamic, libraries and linking:
Creation of a Simple Static LibrarySuppose that you can distribute all the routines in a program over a group of source files and that these files are wholly contained in the subdirectory test_lib/. Suppose further that the files are organized in such a way that they each contain a single principal subprogram that would be called by the user program, along with any "helper" routines that the subprogram might call but that are called from no other routine in the library. Also, any helper routines called from more than one library routine are gathered together into a single source file. This gives a reasonably well-organized set of source and object files. Assume that the name of each source file is taken from the name of the first routine in the file, which in most cases is one of the principal files in the library: demo% cd test_lib demo% ls total 14 2 dropx.f 2 evalx.f 2 markx.f 2 delte.f 2 etc.f 2 linkz.f 2 point.f The lower-level "helper" routines are gathered together into the file etc.f. The other files can contain one or more subprograms. First, compile each of the library source files, using the -c option, to generate the corresponding relocatable .o files: demo% f77 -c *.f
delte.f:
delte:
q_fixx:
dropx.f:
dropx:
etc.f:
q_fill:
q_step:
q_node:
q_warn:
...etc
demo% ls
total 42
2 dropx.f 4 etc.o 2 linkz.f 4 markx.o
2 delte.f 4 dropx.o 2 evalx.f 4 linkz.o 2 point.f
4 delte.o 2 etc.f 4 evalx.o 2 markx.f 4 point.o
demo%
Now, create the static library testlib.a using ar: demo% ar cr testlib.a *.o To use this library, either include the library file on the compilation command or use the -l and -L compilation options. The example uses the .a file directly: demo% cat trylib.f
C program to test testlib routines
x=21.998
call evalx(x)
call point(x)
print*, 'value ',x
end
demo% f77 -o trylib trylib.f test_lib/testlib.a
trylib.f:
MAIN:
demo%
Notice that the main program calls only two of the routines in the library. You can verify that the uncalled routines in the library were not loaded into the executable file by looking for them in the list of names in the executable displayed by nm: demo% nm trylib | grep FUNC | grep point [146] | 70016| 152|FUNC |GLOB |0 |8 |point_ demo% nm trylib | grep FUNC | grep evalx [165] | 69848| 152|FUNC |GLOB |0 |8 |evalx_ demo% nm trylib | grep FUNC | grep delte demo% nm trylib | grep FUNC | grep markx demo% ..etc In the preceding example, grep finds entries in the list of names only for those library routines that were actually called. Another way to reference the library is through the -llibrary and -Lpath options. Here, the library's name would have to be changed to conform to the libname.a convention: demo% mv test_lib/testlib.a test_lib/libtestlib.a demo% f77 -o trylib trylib.f -Ltest_lib -ltestlib trylib.f: MAIN: The -llibrary and -Lpath options are used with libraries installed in a commonly accessible directory on the system, like /usr/local/lib, so that other users can reference it. For example, if you left libtestlib.a in /usr/local/lib, other users could be informed to compile with the following command: demo% f77 -o myprog myprog.f -L/usr/local/lib -ltestlib Replacement in a Static LibraryIt is not necessary to recompile an entire library if only a few elements need recompiling. The -r option of ar permits replacement of individual elements in a static library. Example: Recompile and replace a single routine in a static library: demo% f77 -c point.f demo% ar r testlib.a point.o demo% Ordering Routines in a Static LibraryTo order the elements in a static library when it is being built by ar, use the commands lorder(1) and tsort(1): demo% ar cr mylib.a 'lorder exg.o fofx.o diffz.o | tsort' Creating Dynamic LibrariesDynamic 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 LibrariesDynamic 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 -picPosition-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 OptionsYou 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 | -dnAllows 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 EnvironmentsSome 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 ConventionsTo 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 LibraryBuilding 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. Libraries Provided with Sun Fortran CompilersThe table shows the libraries installed with the compilers. Table 4-1 Major Libraries Provided With the Compilers
See also the math_libraries README file for more information. VMS LibraryThe libV77 library is the VMS library, which contains two special VMS routines, idate and time. To use either of these routines, include the -lV77 option. For idate and time, there is a conflict between the VMS version and the version that traditionally is available in UNIX environments. If you use the -lV77 option, you get the VMS compatible versions of the idate and time routines. See the Fortran Library Reference Manual and the FORTRAN 77 Language Reference Manual for details on these routines. POSIX LibraryThere are two versions of POSIX bindings provided with FORTRAN 77:
If you pass bad handles:
Of course, the checking is time-consuming, and libFposix_c is several times slower. Both POSIX libraries come in static and dynamic forms. The POSIX bindings provided are for IEEE Standard 1003.9-1992. IEEE 1003.9 is a binding of 1003.1-1990 to FORTRAN (X3.8-1978). For more information, see these POSIX.1 documents:
To find out precisely what POSIX is, you need both the 1003.9 and the POSIX.1 documents. The POSIX library for f90 is libposix9. Shippable LibrariesIf your executable uses a Sun dynamic library that is listed in the runtime.libraries README file, your license includes the right to redistribute the library to your customer. This README file is located in the READMEs directory: <install-point>/SUNWspro/READMEs/ Do not redistribute or otherwise disclose the header files, source code, object modules, or static libraries of object modules in any form. Refer to your software license for more details. |
||||||||||||||||||||||||||||||||||||||||||||||||