Static And Shared C Libraries

C Libraries

What is a library:

A library is simply a file that contains or rather groups together multiple compiled object code files to a single file that is to be incorporated later into a program.

Functions which are to be shared by more than one application should be compiled and bundled into a library.

Main Benefits of using libraries:

  • Allows program(s) to be more modular
  • Reduces code size and hence (re)compilation time
  • Simplifies the multiple use and sharing of software components among applications
  • Each and every object file need not be stated while linking, instead the individual library can be referenced
Library Types in Linux:
  • Static Libraries
  • Shared Libraries
Static Libraries came into existence first and are simpler to explain. A static library allows user to link to the programs without having to recompile its code. However, given today's faster systems and compilers, it is not so significant as it once was. They are however, often useful for the programmers who wish to permit others to link to their library but don't want to provide the library source code.

Shared Libraries are loaded by programs when they start. The file is designed so that the code is position-independent and can be loaded anywhere in the memory. An application can load and unload the shared libraries when required. This process is generally handled by an interpreter(usually ld.so) which links the required shared object to the application at runtime. Following benefits in Linux make Shared Libraries preferable over static libraries:
  • Allow you to update the libraries and still support the programs which use older, non-backward compatible versions of same libraries
  • Allow you to override specific libraries or functions in a library when executing the program
  • No need to stop the program running existing libraries to do all this
Creating libraries and using them in the code

Lets consider a simple example of creating a library that contains most basic code which returns the sum of two integers and using it. (The code is for demonstration purpose and doesn't handle very large integers values properly)

Sample code for the library:

static and shared library - 1
This code goes into the library. It exhibits one single function that takes two ints, calculates their sum value and returns it. Let us name the file as CodeForLib.c

The Header File

Lets create a header file (CodeForLib.h) for the same with following contents:

 static and shared library - 2


The Program using the library:
This is a sample program (CodeToRun.c) that shall use the function from library to obtain sum of two integers

static and shared library - 3

Creating a static library

A static library is basically a set of object files that are copied into a single file. This single file is the static library. The static file is created with the archiver (ar).


First, we create object file CodeForLib.o from the c file CodeForLib.c as

static and shared library - 4


Now, the archiver (ar) is invoked to produce a static library (named libSum.a) out of the object file CodeForLib.o

static and shared library - 5
Note: the library name must start with the three letters lib and end with the suffix .a.

Linking against static library
Now the CodeToRun.c can be associated with the static library as:
static and shared library - 6

Note: the first three letters (lib), as well as the suffix (.a) must not be specified. The rest of the library name should be prefixed by -l. So, in the example, for libSum.a, we specify -lSum


Running the executable

We now have executable created as static_linked in previous step. It can be simply run as ./static_linked to get the following output
static and shared library - 7

As we are now clear with static library creation, we can move on to Shared Libraries.
Using the same code we shall now create and link to a shared library.

Creating the shared library

As mentioned above, the code with static libraries is position independent. The -fPIC option tells gcc to create object file(CodeForLib.o) with position independent code as

static and shared library - 8


Next, the shared library (libSum.so) is generated as:
static and shared library - 9
Note: the library name must start with the three letter lib and end with the suffix .so

Linking against shared library(Dynamic linking)
Now the CodeToRun.c can be associated with the shared library as:
static and shared library - 10

Note: the first three letters (lib), as well as the suffix (.so) must not be specified. The rest of the library name should be prefixed by -l. So, in the example, for libSum.so, we specify -lSum


Running the executable

We now have executable created as dynamically_linked in previous step.
The procedure is mentioned in many books is to specify the LD_LIBRARY_PATH as
LD_LIBRARY_PATH=./dynamically_linked

However, this did not work for me. Digging a little more, I found that in some books, it was specified to use -L option while linking the code with shared library as
static and shared library - 11

Alas! this one also did not work but it threw the following error:
static and shared library - 12

The good old Hit and Trial method came to rescue.
 
To get it working, I had to create a soft link from inside /usr/lib targeting the library libSum.so as
static and shared library - 13

After this, executing as ./dynamically_linked goes well to provide the following output
static and shared library - 14

Thats all....Now you should be clear with static and shared libraries, how to create your own and use them.

The mentioned examples were compiled and run with standard gcc compiler on FreeBSD.

Happy Programming!!
:)
comments powered by Disqus