2.7 Linking with external libraries
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 section 10 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.a' 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.