Next: Using library header files, Previous: A simple makefile, Up: Compiling a C program [Contents][Index]
A library is a collection of precompiled object files which can be
linked into programs. The most common use of libraries is to provide
system functions, such as the square root function sqrt
found in
the C math library.
Libraries are typically stored in special archive files with the
extension .a, referred to as static libraries. They are
created from object files with a separate tool, the GNU archiver
ar
, and used by the linker to resolve references to functions at
compile-time. We will see later how to create libraries using the
ar
command (see Compiler-related tools). For simplicity,
only static libraries are covered in this section—dynamic linking at
runtime using shared libraries will be described in the next
chapter.
The standard system libraries are usually found in the directories /usr/lib and /lib.5 For example, the C math library is typically stored in the file /usr/lib/libm.so on Unix-like systems. The corresponding prototype declarations for the functions in this library are given in the header file /usr/include/math.h. The C standard library itself is stored in /usr/lib/libc.a and contains functions specified in the ANSI/ISO C standard, such as ‘printf’—this library is linked by default for every C program.
Here is an example program which makes a call to the external function
sqrt
in the math library libm.a:
#include <math.h> #include <stdio.h> int main (void) { double x = sqrt (2.0); printf ("The square root of 2.0 is %f\n", x); return 0; }
Trying to create an executable from this source file alone causes the compiler to give an error at the link stage:
$ gcc -Wall calc.c -o calc /tmp/ccbR6Ojm.o: In function `main': /tmp/ccbR6Ojm.o(.text+0x19): undefined reference to `sqrt'
The problem is that the reference to the sqrt
function cannot be
resolved without the external math library libm.a. The function
sqrt
is not defined in the program or the default library
libc.a, and the compiler does not link to the file libm.a
unless it is explicitly selected.
Incidentally, the file mentioned in the error message
/tmp/ccbR60jm.o is a temporary object file created by the
compiler from calc.c, in order to carry out the linking process.
To enable the compiler to link the sqrt
function to the main
program calc.c we need to supply the library libm.a. One
obvious but cumbersome way to do this is to specify it explicitly on the
command line:
$ gcc -Wall calc.c /usr/lib/libm.a -o calc
The library libm.a contains object files for all the mathematical
functions, such as sin
, cos
, exp
, log
and
sqrt
. The linker searches through these to find the object
file containing the sqrt
function.
Once the object file for the sqrt
function has been found, the
main program can be linked and a complete executable produced:
$ ./calc The square root of 2.0 is 1.414214
The executable file includes the machine code for the main function and
the machine code for the sqrt
function, copied from the corresponding
object file in the library libm.a.
To avoid the need to specify long paths on the command line, the compiler provides a short-cut option ‘-l’ for linking against libraries. For example, the following command,
$ gcc -Wall calc.c -lm -o calc
is equivalent to the original command above using the full library name /usr/lib/libm.a.
In general, the compiler option -lNAME will attempt to link object files with a library file libNAME.a in the standard library directories. Additional directories can specified with command-line options and environment variables, to be discussed shortly. A large program will typically use many -l options to link libraries such as the math library, graphics libraries and networking libraries.
• Link order of libraries: |
On systems supporting both 64 and 32-bit executables, their libraries are stored in the directories /lib/x86_64-linux-gnu and /usr/lib/x86_64-linux-gnu, or /lib64 and /usr/lib64 for 64-bit libraries; and /lib/i386-linux-gnu and /usr/lib/i386-linux-gnu, or /lib and /usr/lib for 32-bit libraries, instead. see Multi-architecture support
Next: Using library header files, Previous: A simple makefile, Up: Compiling a C program [Contents][Index]