We explored what libraries are and how to use them in a previous
chapter. (See Libraries, if you need to refresh your memory.) You
may have wondered how libraries are written in the first place. Is the
whole process too complicated for a mortal C programmer to attempt? Not
at all.
Suppose you have a function (or set of functions) that you would like to
use widely across the various C programs you write. You might even like
to make it available to other users in a convenient way. To create a
code library that will enable you to achieve this, follow the sequence
below. We will use a code example, but you can create your own library
by taking similar steps.
Here's an example of the kind of function you might like to use in
multiple programs. It accepts one string containing some text to print,
and then prints it on the default printer.
For the sake of example, the file below is named lpr_print.c.
To create a static library called liblprprint.a containing this
function, just type the following two command lines in your GNU shell:
gcc -c lpr_print.c
ar rs liblprprint.a lpr_print.o
The -c option to gcc produces only a .o object code file,
without linking it, while the ar command (with its rs options)
permits the creation of an archive file, which can contain a bundle of other
files that can be re-extracted later (for example, when executing library code).
In this case, we are only archiving one object code file, but in some cases, you might
want to archive multiple ones. (See the man page for ar
for more information.)
To create a shared library called liblprprint.so instead, enter
the following sequence of commands:1
(For the record, pic stands for "position-independent code", an
object-code format required for shared libraries. You might need to use
the option -fPIC instead of -fpic if your library is
very large.)
Now create a header file that will allow users access to the functions
in your library. You should provide one function prototype for each
function in your library. Here is a header file for the library we
have created, called liblprprint.h.
/*
liblprprint.h:
routines in liblprprint.a
and liblprprint.so
*/
extern void lpr_print (char *the_text);
Now you should put your libraries and include file somewhere your code
can access them. For the sake of this example, create the directories
include and lib in your home directory. Once you have
done so, move the .a and .so files you have created to
lib, and the .h file to include.
If you have taken the last step, and you want to run a program linked to
a shared version of your library, you should type a line like the
following into your shell (the following command line assumes you are
using the Bash shell and that your home directory is named
/home/fred):
This command line sets an environment variable that makes the linker
search the /home/fred/lib directory before it searches anywhere
else. You can include it in your .bashrc or .bash_profile
file. If you don't execute this command before you attempt to run a program
using your shared library, you will probably receive an error.
Now you can write programs that use your library. Consider the following
short program, called printer.c:
#include <liblprprint.h>
/* To shorten example, not using argp */
int main ()
{
lpr_print ("Hello, Multiverse!\nHowarya?\n");
return 0;
}
To compile this program using your static library,
type something like the following command line:
The --static option forces your static library to be linked;
the default is your shared version. The -llprprint option
makes GCC link in the liblprprint library, just as you would need
to type -lm to link in the libm math library.
The -I../include and -L../lib options specify that the
compiler should look in the ../include directory for include
files and in the ../lib directory for library files. This
assumes that you have created the include and lib
directories in your home directory as outlined above, and that you are
compiling your code in a subdirectory of your home directory. If you
are working two directories down, you would specify
-I../../include, and so on.
The above command line assumes you are using only one .c
source code file; if you are using more than one, simply include them
on the command line as well. (See Compiling multiple files.)
Note:
Using the --static option will force the compiler to link
all libraries you are using statically.
If you want to use the static version of your library,
but some shared versions of other libraries, you can omit the
--static option from the command line and specify the
static version of your library explicitly, as follows:
The executable produced is called printer. Try it!
Footnotes
To create library files
containing multiple object files, simply include the object files on the
same command line. For example, to create a static library with
multiple object files, type a command such as ar rs
liblprprint.a lpr_print.o lpr_print2.o lpr_print3.o. Similarly, to
create a shared library, type gcc -shared -o liblprprint.so
lpr_print.o lpr_print2.o lpr_print3.o.