C Shared Libraries – Static and Dynamic

As a programmer I often find myself having to decide not only how to organize my code within a set of files, but also deciding if this code may be used by another program for some inter-process communication or as a generic piece of code that I could see many other programs using, a utilities library for example. This leads to the idea of shared components or shared libraries. These libraries may be referenced (linked) by your program during compilation or loaded during runtime with a set of tools. In fact, if you have done any threaded work on a Linux system you have probably come across a reference to -lpthread. This tells the compiler to link to that library during compilation. A library is also a way of releasing an API to interface with an application instead of having to compile in those functions. Libraries also reduce the size of a program because the code is in one single place and may be referenced by many applications at once.

Types of Linux Libraries

In Linux there are two types of C/C++ libraries that can be made.

  • Dynamically linked shared object libraries (*.so) files.
  • Static libraries (*.a) files, this is linked in and becomes part of the application.

The dynamic shared object files can be linked at runtime, and must be already compiled and reachable during the compilation and linking phase, and are not included within the executable. The other option is to load and unload using the dynamic linking system.

The naming schemes include the prefix of lib, if you look in the /usr/lib/ directory you will see a few hundred libraries used by your running Linux system. When linking against your program you simply use -l then the name, so for p-threads as shown above you link with -lpthread.

How Do You Generate A Static Library?

To create a static library (ending in *.a) you compile your program as you would normally:

gcc -Wall -c temp_test.c

This will create a library_data.o file, or object file. To create the library the next step is to use the ar utility.

ar -cvq libtemp_test.a temp_test.o

Voila, you now have a static library that can be used during the compilation phase. For example:

gcc -o eriks_program eriks_program.c libtemp_test.a
--- OR ---
gcc -o eriks_program eriks_program.c -ltemp_test

How Do You Generate A Dynamic Library?

When creating the dynamic library a few more flags during compilation are required. The creation of the object code or object file is required in the same way it is for the static library, however the -fPIC flag is required. It states that position independent code needs to be outputted for a shared library. Here are the steps required:

gcc -Wall -fPIC -c temp_test.c
gcc -shared -Wl,-soname,libtemp_test.so.1 -o libtemp_test.so.1.0 temp_test.o
mv libtemp_test.so.1.0 /lib
ln -sf /lib/libtemp_test.so.1.0 /lib/libtemp_test.so
ln -sf /lib/libtemp_test.so.1.0 /lib/libtemp_test.so.1

These steps create the libtemp_test.so.1.0 library as well as the symbolic links that allow compilation against -ltemp_test and run time binding. So what do these compiler options mean? I will save you the trouble from having to look them up:

  1. -Wall: include warnings.
  2. -fPIC: Compiler directive to output position independent code, a characteristic required by shared libraries.
  3. -shared: Produce a shared object which can then be linked with other objects to form an executable.
  4. -W1: Pass options to linker.

Now to compile a program using the libtemp_test.so.1.0 library you simply:

gcc -Wall -I/path/to/include-files -L/path/to/libraries eriks_program.c -ltemp_test -o eriks_program
--- OR ---
gcc -Wall -L/lib eriks_program.c -ltemp_test -o eriks_program

Et voila!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *