Static And Shared 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
- Static Libraries
- Shared Libraries
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
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:
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:
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
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
First, we create object file CodeForLib.o from the c file CodeForLib.c as
Now, the archiver (ar) is invoked to produce a static library (named libSum.a) out of the object file CodeForLib.o
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:
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 executableWe now have executable created as static_linked in previous step. It can be simply run as ./static_linked to get the following output
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
Next, the shared
library (libSum.so) is generated as:
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:
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 executableWe 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
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
Alas! this one also did not work but it threw the following error:
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
After this, executing as ./dynamically_linked goes well to provide the following output
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!! :)