Node:Building a library, Next:Questions 17, Previous:Writing a makefile, Up:Putting a program together
Building a library
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.#include <stdio.h> void lpr_print (char *the_text) { FILE *printer; printer = popen ("lpr", "w"); fprintf (printer, the_text); pclose (printer); }(See Programming with pipes, for the rationale behind this function.)
-
Now we will create a library.
- To create a static library called
liblprprint.acontaining 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
-coption togccproduces only a.oobject code file, without linking it, while thearcommand (with itsrsoptions) 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 themanpage forarfor more information.) - To create a shared library called
liblprprint.soinstead, enter the following sequence of commands:1gcc -c -fpic lpr_print.c gcc -shared -o liblprprint.so lpr_print.o
(For the record,
picstands for "position-independent code", an object-code format required for shared libraries. You might need to use the option-fPICinstead of-fpicif your library is very large.)
- To create a static library called
- 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
includeandlibin your home directory. Once you have done so, move the.aand.sofiles you have created tolib, and the.hfile toinclude. -
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):export LD_LIBRARY_PATH=/home/fred/lib:$LD_LIBRARY_PATH
This command line sets an environment variable that makes the linker search the
/home/fred/libdirectory before it searches anywhere else. You can include it in your.bashrcor.bash_profilefile. 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:
gcc --static -I../include -L../lib -o printer printer.c -llprprint
The
--staticoption forces your static library to be linked; the default is your shared version. The-llprprintoption makes GCC link in theliblprprintlibrary, just as you would need to type-lmto link in thelibmmath library.The
-I../includeand-L../liboptions specify that the compiler should look in the../includedirectory for include files and in the../libdirectory for library files. This assumes that you have created theincludeandlibdirectories 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
.csource 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
--staticoption 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--staticoption from the command line and specify the static version of your library explicitly, as follows:gcc -I../include -L../lib -o printer printer.c ../lib/liblprprint.a
- To compile this program using your shared library, type
something like the following command line.
gcc -I../include -L../lib -o printer printer.c -llprprint
- 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, typegcc -shared -o liblprprint.so lpr_print.o lpr_print2.o lpr_print3.o.