Create C Program with Shared Library (Dynamic Link Library) in Linux

Shared Library (Dynamic Link Library)

Shared library (a.k.a dynamic link library) is a library file that is called and linked by a dynamic linker during program execution time.

Naming Convention
In Linux, all shared library are name with a prefix lib and ends with .so. The actual file name of a shared library should follow the convention follow by a period and a version number, follow by a period and a minor version number follow by a period and a release number. Therefore a shared library file should be named as: libmymath.so.1.0.1.

Please note that you also need to create a so name file using the same file name but without the minor version and release number. Therefore a shared library file should be named as: libmymath.so.1.

You will also need a linker name using the file name as so name but without the version number. Therefore a shared library file should be named as: libmymath.so

A typical shared library should list as actual file, so name file and linker named file, as shown below:
libmymath.so.1.0.1
libmymath.so.1 -> libmymath.so.1.0.1
libmymath.so -> libmymath.so.1

Program Example
We will be creating a shared library file with the following headers and program.

The headers file named libmymath.h should contain the following:

#define PI 3.1415

double CircleArea (double radius);
double CircleCircumference (double radius);

double PowerOf2 (double number);
double PowerOf3 (double number);

The library program file libmymath1.c contains the following code:

#include "libmymath.h"

double CircleArea (double radius)
{
 return radius * radius * PI;
}

double CircleCircumference (double radius)
{
 return 2 * radius * PI;
}

The library program file libmymath2.c contains the following code:

#include "libmymath.h"

double PowerOf2 (double number)
{
 return number * number;
}

double PowerOf3 (double number)
{
 return number * number * number;
}

Compiling a Shared Library

In order to create a shared library, you need to compile the library program into a position independent code. The command to use is as follows:
gcc -fPIC -Wall -c -g libmymath1.c

This command create an object file libmymath1.o
-fPIC is to produce PIC(position independent code)
-g write debugging info into object file, this is optional but recommended

Use the same command to compile the second library program file libmymath2.c.

Create Library Files

Next, we need to create the library file named libmymath.so.1.0.1 with so name. The command is as follows:
gcc -shared -Wl,-soname,libmymath.so.1 -o libmymath.so.1.0.1 libmymath1.o libmymath2.o

Now, we need to configure the soname and create a soft link for libmymath.so.1. Use the following command:
ldconfig -n ./

Next, we need to create another soft link for the linker
ln -s libmymath.so.1 libmymath.so

Now we have 3 files as below:
libmymath.so.1.0.1
libmymath.so.1
libmymath.so

Distribution of Library Files

(Note: This section require user to use root privilege, use the command su)

According to the FHS (Filesystem Hierarchy Standard), it is recommended that most libraries should be installed in /usr/lib; libraries that are required for startup should be in /lib and libraries that are not part of the system should be in /usr/local/lib. If you are programming for Linux OS then your libraries should be either in /lib or /usr/lib. For application program it is recommend to install the libraries at /usr/local/lib.

For RedHat based system /usr/local/lib is not in the default search path. There are additional work involved. You either need to create a conf file or you can change the settings in /etc/ld.so.conf. The recommended method is to create a conf file as follows:
echo /usr/local/lib >> /etc/ld.so.conf.d/mylib.conf

Now, we can move library files to /usr/local/lib:
mv libmymath.so.1.0.1 libmymath.so.1 libmymath.so /usr/local/lib 

Finally, we need to run ldconfig to reload the cache. Every time when a new shared library is added, ldconfig must be run to recreate the symbolic link to the cache.
ldconfig

Note: Remember to use root privilege for all the commands in this section. Please note that cp command does not work when copying soft link to a new location. You can only copy the actual file.

Create Application Program

The application program that uses the shared library is listed below:

#include <stdio.h>
#include "libmymath.h"

int main ()
{
 double r = 4.0;
 double n = 5.0;

 printf ("Radius %.2f, area is %.2f \n", r, CircleArea(r));
 printf ("Radius %.2f, circumference is %.2f \n", r, CircleCircumference(r));
 printf ("%.2f to the power of 2 is %.2f \n", n, PowerOf2(n));
 printf ("%.2f to the power of 3 is %.2f \n", n, PowerOf3(n));

 return 0;
}

Compiling and Testing the Application

To compile the application, use the command:
gcc -Wall app1.c -o app1 -lmymath

Next we need to test if the application can locate the share library. Use the command ldd  as follows:
ldd app1

Note: Make sure under libmymath.so.1 is pointed to the correct file under /usr/local/lib. If you encounter this error "libmymath.so.1 => not found", this error indicates that the system could not find the library file. If you encounter such error, make sure that the default search path is properly configure especially for Fedora, CentOS and Red Hat system. You might need to run ldconfig again to refresh the cache.

BEWARE: DO NOT run ldd on program that you do not trust as it is possible for an untrusted program to force the ldd user to run arbitrary code.

Now, you can run the application as follows:
./app1

Note:
The most common error for using shared library is when the system could not locate the library file. Another common error happens when there are multiple versions of the library file.

Additional Tools
You can use the command nm to examine the library file and list the functions. Use nm -s -D lib<filename>.so.1.0.1 to list the functions in the library file:
nm -s -D libmymath.so.1.0.1


The instructions above is a simple guide to create a dynamic link library. Please note that the subject of software library management is a complex one. More research should be done for managing large and complex libraries.

***** 

Comments

Popular posts from this blog

Revive Old Mac Mini (2009) with Linux

Configure Unattended Upgrades on Raspberry Pi

Install and Configure RealVNC in Linux Ubuntu 18.04 LTS