UC San Diego SearchMenu

Subroutine libraries, static and dynamic linking

This article describes subroutine libraries, describes the function of the loader, explains how to find appropriate Unix subroutines, and how to compile programs which use them. For the purposes of this article the terms "subroutine" and "routine" are interchangable.

Many useful predefined routines are provided in files called libraries. Library routines can be linked with user defined routines to build complete executable programs.

In order to use certain routines it is necessary to place #include instructions at the beginning of your program source files.

Linking

The process of linking involves scanning the user's compiled object code for references to routines which have not been defined by the user, then attempting to find those routines in libraries. In most cases, the link editor "ld" is invoked indirectly through a compiler. Each of the compilers specifies a certain default set of libraries to the link editor. If a program calls routines which are in other libraries, the user must specify the library in the compile command or else the routine will not be found by the link editor, the routine will be left undefined, and the program will not be runable.

Loading, static and dynamic

When a program is run, the object code for the library routines it uses must be available. One way this can be assured is by loading the code for the library routines into the executable file during the linking phase. This approach is called "static linking." One disadvantage of static linking is that the code for various library routines is redundantly stored in the executable files of many different programs and utilities. This wastes a lot of disk space.

Another approach is to defer loading until the program is run, at which time routines are loaded from libraries on the fly. This is called "dynamic linking." It saves disk space, but the viability of dynamically linked programs depends on being able to find the library files not only at compile time, but again at run time. Various complications arise if libraries are updated or moved between compile and run time, or if the program is compiled and linked on one system and then moved to another where the libraries are not stored in the same locations. On SUN based systems, the environment variable LD_LIBRARY_PATH may be used to assist the dynamic link editor in locating libraries at run time. See the accompanying article on that topic, and "man ld.so" for details.

How to locate appropriate routines

Basic Unix libraries

Routines in basic Unix libraries are documented in sections 2 and 3 of the Unix Programmer's Manual. Those in section 2 are system calls which are the building blocks of the higher level routines in section 3. A good way to begin your search for an appropriate routine is to read the introduction to section 3 of the manual. To display it on-line, type:

% man 3 intro

The introduction gives a synopsis of all section 3 routines. For example, the cosine routine "cos" is shown as

cos        sin.3m          trignometric function

The "sin.3m" portion indicates that the article describing cos is named "sin". You can display the article by typing:

man 3m sin

The "3m" denotes the classification containing all the routines in the math library. Classifications are useful guideposts in determining the appropriate procedures for using routines, more on this later. The section 3 classifications are:

 3 standard C library
 3f     standard FORTRAN library
 3s     stdio
 3m     math library
 3x     miscellaneous

Another way to look for routines is to use the keyword search facility of the man command. For example, to look for a routine which computes absolute values, type:

% man -k absolute

In this case the following would appear:

abs (3)                    - integer absolute value
fabs, floor, ceil, rint (3M)    - absolute value, floor, ceiling, and
                                  round-to-nearest functions
hypot, cabs (3M)        - Euclidean distance, complex absolute value

This let's you know that there are three articles which have the word "absolute" in their brief description. You can display them by typing the following:

% man 3 abs
% man 3m fabs
% man 3m hypot

Notice that the first routine on the line usually serves as the name that is used to retrieve the article. In cases where this is not true you have to go back to "man 3 intro" to find the retrieval name.

The man -k keyword search may reveal articles from other sections of the manual including ones covering the routines (system calls) in section 2. For more information on how to use the 'man -k' command see:

% help 
man

Once you have found a routine that does what you want, make note of its classification (2, 3, 3f, 3s, ...). The classifications are:

 2 or 3      standard C library
 3f       standard FORTRAN library
 3s       stdio
 3m       math library
 3x       miscellaneous

For additional information about basic Unix libraries see:

% man 2 intro
% man 3 intro
% man 3f intro

How to compile with library routines

Basic Unix Libraries

Routines in standard C library (2 or 3)

Using some routines in the C library requires that you place #include instructions at the beginning of your source code file. Look at the synopsis section of the manual article for the routine you intend to use. If #include instructions are required, they will be shown there. For example, the "man 3 ctype" article shows:

#include <ctype.h>

This means you must put a copy of that line at the beginning of your program source file.

The C and Pascal compilers automatically provide the C library for loading. Note: special procedures must be followed in order to call C routines from Pascal programs.

Routines in standard FORTRAN library (3f)

All these routines except those in plot(3f) may be used in f77 programs without taking special measures, the compiler automatically provides them for loading.

For the instructions on how to use the plot(3f) library, type:

% man 3f plot
Routines in stdio (3s)

To use a routine in stdio, you must put the following line before your first executable statement:

#include <stdio.h>

In all other respects usage is the same as for the C library. The stdio routines are in fact now part of the C library.

Routines in the math library (3m)

The C math library contains many algebraic, IEEE, Bessel, and trigonometric functions. Such functions include:

sin(), cos(), atan(), log(), pow(), sqrt(), exp(), lgamma()

A comprehensive list of all functions can be obtained by issuing the command:

% man 3m intro

To use a routine in the math library, you must put the following line before your first executable statement:

#include <math.h>

and you must also specify the math library when you compile. This is done by putting a -lm at the end of the cc command. Note the option letter is a lowercase L, not a numeral one. For example, to compile the C program foo.c which uses math functions you would type:

% cc foo.c -lm
Routines in the miscellaneous libraries (3x)

To use a subroutine from a miscellaneous library (3x), you must place any required #include instructions in you source code files, see the discussion above.

Also you need to determine the name of the library in order to specify it for loading. The manual articles for 3x routines vary in the way that they show the library name. Some show the full pathname of the file containing the library, e.g. /usr/lib/lib???.a where ??? is the name for the library. Others show the name as -l???, the way it would usually be specified in a cc command:

cc prog.c -l???

Note the option letter is a lowercase L, not a numeral one.

Add-on libraries

(using -I and -L)

Add-on libraries (using -I and -L)

Here are some of the issues involved in compiling programs which use routines in add-on libraries:

  • You may need to put "#include" directives in your source file(s). Documentation for the library should tell you if "#include" directives are required.
  • If "#include" directives are used, you probably will need to indicate the location of the include-file directory. This is done with the -I option (see below).
  • You need to specify the name of the add-on library. This is done with -l (lowercase L, not numeral one).
  • You will probably need to indicate the location of the add-on library directory. This is done with -L.

As an example let's consider the program "basecalc" from the O'Reilly and Associates' Xlib Programming Manual. It contains the following X related #include directives:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/cursorfont.h>

It uses routines in two X libraries, Xext and X11. As of this writing (May 92) the necessary X include files and libraries are part of the OpenWindows distribution which is installed on many ACMS systems. The include-file directory is /usr/openwin/include and the library directory is /usr/openwin/lib.

In the library directory the "X11" library files are libX11.a (for static linking) and libX11.so.4.10 (for dynamic linking). The option "-lX11" refers to one or the other of those library files depending on whether you select static linking or go with the default, dynamic linking. Likewise for -lXext.

The program is compiled and linked with these commands:

cc -O -I/usr/include -I/usr/openwin/include -target sun4 -c basecalc.c
cc -o basecalc basecalc.o -O -lXext -lX11 -L/usr/openwin/lib

To avoid typing long commands for each compile it is advisable to use the "make" facility in conjunction with a Makefile.

Specifying libraries in proper order

If more than one library is specified in a compiler command, the order in which the libraries are listed is important. This is due to the fact that library routines must be called before they are defined. For example, routines in the UNIX curses library call routines from the UNIX termlib library, so to compile a C program ``screen.c'' which calls routines from the curses library, the curses library must be specified before the termlib library:

   % cc  screen.c  -lcurses  -ltermlib

Using LD_LIBRARY_PATH to assist dynamic loading

As was discussed in the introductory portion of this article, when a dynamically linked program is run, the dynamic link editor (ld.so) must be able to locate appropriate shared libraries in order to obtain the object code for the routines which were dynamically linked. This is straight forward if the shared libraries are in the same location they were in when the program was compiled and linked, however if the libraries are in some other location, it usually will be necessary to assist the link editor in finding them.

You can point out the existence of a library directory by setting the shell environment variable LD_LIBRARY_PATH. For example,

setenv LD_LIBRARY_PATH /software/common/X11R5/lib

Since a LD_LIBRARY_PATH setting could mis-direct other programs which do not need it, or which may need a different LD_LIBRARY_PATH setting, the safest way to specify LD_LIBRARY_PATH for a particular program is to create an alias which sets the variable in a sub-shell. A sub-shell is created as a result of the parentheses in the following example.

alias dbt '(setenv LD_LIBRARY_PATH /usr/openwin/lib; /usr/lang/dbxtool \!* )'

For more information about LD_LIBRARY_PATH see "man ld.so"