Libraries consist of a set of related functions to perform a common task; for example, the standard C library, libc.a, is automatically linked to your programs by the GCC compiler and can be found at /usr/lib/libc.a. Standard system libraries are usually found in /lib and /usr/lib/ directories.
By default, the GCC compiler, or more specifically its linker needs to be directed to which libraries to search other than the standard C library - which is included by default.
There are a number of conventions for naming libraries and telling the compiler where to find them that we will discuss in this lecture. A library file name always starts with lib. The last part of the name determines what type of library it is:
.a static, traditional libraries. Applications link to these libraries of object code.
.so dynamically linked shared object libraries. These libraries can either be linked in at run-time but statically aware or loaded during execution by the dynamic link loader.
The way to view a static library is that it is linked by the linker and included in the execution code. So if 10 applications are linked in a static library it would mean that each application's resulting binary would include the referenced library in its program binary. This leads to large executable files. To address these people use shared libraries. These libraries contain the same references as those found in static ones but the code for those functions are not directly included in the resulting executable. Rather, shared libraries access a single copy of the library that is shared by all the 10 applications while all executing at the same time. There is some operating system magic to make this happen safely but it is a foundation of modern computing.
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);
}
Now we will create a library
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
gcc -c -fpic lpr_print.c
gcc -shared -o liblprprint.so lpr_print.o
(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 ):
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/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>
int main ()
{
lpr_print ("Hello\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 --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.
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:
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.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.