Create a library in C? Static or dynamic
By: Daniel Cortes
Tags: C Static Library, C Programming Language, Programming Languages, Dynamic Library, Code

When we want to go to a place where there are only books, we run to a library. Here, we can find in a ordered way all kind books, history, science fiction (this is one of my favorite). When you are writing a program, we also need to use libraries. But here, instead of books, you can find diferents function that performs specifics operations. You can do amazing aplications that would see like a science fiction to the users.

In this articule, I’m going to talk about libraries in C programming language, mother of all language.

Summarizing what you will find in this articule:

C standard libraries

Why using libraries in general

How do they work

How to create them (Linux only)

How to use them (Linux only)

What are the differences between static and dynamic libraries

C standard libraries

The C language provides no built-in facilities for performing such common operations as input/output, memory management, string manipulation, and the like. Instead, these facilities are defined in a standard library, which you compile and link with your programs. Each standard library function is declared in one or more of the standard headers. These headers also contain all the macro and type definitions that the C standard provides. Each of the standard headers contains a set of related function declarations, macros, and type definitions. For example, mathematical functions are declared in the header math.h.

There are advantages of Using C standard library functions. One of the most important reasons you should use standard library functions is simply because they work. These functions have gone through multiple rigorous testing and are easy to use.

Since, the functions are “standard library” functions, a dedicated group of developers constantly make them better. The general functions like printing to a screen, calculating the square root, and many more are already written. You shouldn’t worry about creating them once again.

These standard functions are portable, your application is expected to work every time, everywhere. And, these standard library functions help you in that they do the same thing on every computer.

if you want to know more about standard libraries in C, I recommend you read the book Standard C Library by P.J. Plauger .

Ok, that’s a standard library , but you can create your own library! Keep reading and I will show you how.

Why using libraries in general

A library is a file containing several object files, that can be used as a single entity in a linking phase of a program. The library can be indexed, so it is easy to find functions and variables in them. For this reason, linking a program whose object files are ordered in libraries is faster than linking a program whose object files are separate on the disk. Also, using a library, there are fewer files to look for and open, that can speeds up the linking process during the compilation. You can read more about this compilation process in a previous blog (Compilation Process for C Programs).

Image from https://book.g1ng3r.com/binary-analysis/practical-binary-analysis

How do they work

Static libraries are just collections of object files that are linked into the program during the linking phase of compilation, and are not relevant during runtime. They permit users to link to programs without having to recompile its code, saving recompilation time. Note that recompilation time is less important given today’s faster compilers, so this reason is not as strong as it once was. Static libraries are often useful for developers if they wish to permit programmers to link to their library, but don’t want to give the library source code.

Dynamic libraries are linked into the program in two stages. First, during compile time, the linker verifies that all the symbols (again, functions, variables and the like) required by the program, are either linked into the program, or in one of its shared libraries. However, the object files from the dynamic library are not inserted into the executable file. Instead, when the program is started, a program in the system (called a dynamic loader) checks out which shared libraries were linked with the program, loads them to memory, and attaches them to the copy of the program in memory. The standard C library is a shared library, and is used by all C programs. Yet, only one copy of the library is stored in memory at any given time. This means we can use far less memory to run our programs, and the executable files are much smaller, thus saving a lot of disk space as well.

How to create them (Linux only)

We finally arrive where we want,the code part. So, if you want to create a Static library in linux you can go to my previous blog:

For dynamic library, the creation process is very similar to static libraries, I’m going to show with an example:

C files:

First, you have to look for all the C files that contains your functions and that you want to belongs to your dynamic library. These are the files that I’m going to work for this example:

[dynamic_library]$ ls -l

-rw-rw-r — 1 vagrant vagrant 296 Dec 14 11:45 0-isupper.c

-rw-rw-r — 1 vagrant vagrant 373 Dec 14 11:54 0-memset.c

-rw-rw-r — 1 vagrant vagrant 412 Dec 14 11:50 0-strcat.c

-rw-rw-r — 1 vagrant vagrant 622 Dec 14 11:52 100-atoi.c

-rw-rw-r — 1 vagrant vagrant 266 Dec 14 11:53 1-isdigit.c

-rw-rw-r — 1 vagrant vagrant 396 Dec 14 11:48 1-memcpy.c

-rw-rw-r — 1 vagrant vagrant 507 Dec 14 11:57 1-strncat.c

-rw-rw-r — 1 vagrant vagrant 372 Dec 14 11:55 2-strchr.c

-rw-rw-r — 1 vagrant vagrant 231 Dec 14 11:50 2-strlen.c

-rw-rw-r — 1 vagrant vagrant 434 Dec 14 11:51 2-strncpy.c

-rw-rw-r — 1 vagrant vagrant 297 Dec 14 11:48 3-islower.c

-rw-rw-r — 1 vagrant vagrant 210 Dec 14 17:51 3-puts.c

-rw-rw-r — 1 vagrant vagrant 370 Dec 14 11:50 3-strcmp.c

-rw-rw-r — 1 vagrant vagrant 497 Dec 14 11:51 3-strspn.c

-rw-rw-r — 1 vagrant vagrant 323 Dec 14 11:47 4-isalpha.c

-rw-rw-r — 1 vagrant vagrant 423 Dec 14 11:57 4-strpbrk.c

-rw-rw-r — 1 vagrant vagrant 543 Dec 14 11:58 5-strstr.c

-rw-rw-r — 1 vagrant vagrant 248 Dec 14 11:47 6-abs.c

-rw-rw-r — 1 vagrant vagrant 342 Dec 14 11:56 9-strcpy.c

-rw-rw-r — 1 vagrant vagrant 247 Dec 14 12:00 _putchar.c

[dynamic_library]$

2. Convert all .c to object files (.o):

Inside the directory where are all the C files, I apply this command to create the objects files for every file:

[dynamic_library]$ gcc -fPIC -c *.c

[dynamic_library]$

As you have noticed, we created the object files with the -fPIC flag. This flag stands for Position Independent Code (This means it wouldn’t matter where the computer loads the code into memory), a characteristic required by shared libraries. After this,we can see all .o files for each .c file:

[dynamic_library]$ ls -l *.o

-rw-rw-r — 1 vagrant vagrant 1264 Dec 14 18:23 0-isupper.o

-rw-rw-r — 1 vagrant vagrant 1280 Dec 14 18:23 0-memset.o

-rw-rw-r — 1 vagrant vagrant 1368 Dec 14 18:23 0-strcat.o

-rw-rw-r — 1 vagrant vagrant 1480 Dec 14 18:23 100-atoi.o

-rw-rw-r — 1 vagrant vagrant 1264 Dec 14 18:23 1-isdigit.o

-rw-rw-r — 1 vagrant vagrant 1288 Dec 14 18:23 1-memcpy.o

-rw-rw-r — 1 vagrant vagrant 1376 Dec 14 18:23 1-strncat.o

-rw-rw-r — 1 vagrant vagrant 1280 Dec 14 18:23 2-strchr.o

-rw-rw-r — 1 vagrant vagrant 1264 Dec 14 18:23 2-strlen.o

-rw-rw-r — 1 vagrant vagrant 1352 Dec 14 18:23 2-strncpy.o

-rw-rw-r — 1 vagrant vagrant 1264 Dec 14 18:23 3-islower.o

-rw-rw-r — 1 vagrant vagrant 1472 Dec 14 18:23 3-puts.o

-rw-rw-r — 1 vagrant vagrant 1360 Dec 14 18:23 3-strcmp.o

-rw-rw-r — 1 vagrant vagrant 1376 Dec 14 18:23 3-strspn.o

-rw-rw-r — 1 vagrant vagrant 1288 Dec 14 18:23 4-isalpha.o

-rw-rw-r — 1 vagrant vagrant 1328 Dec 14 18:23 4-strpbrk.o

-rw-rw-r — 1 vagrant vagrant 1424 Dec 14 18:23 5-strstr.o

-rw-rw-r — 1 vagrant vagrant 1248 Dec 14 18:23 6-abs.o

-rw-rw-r — 1 vagrant vagrant 1328 Dec 14 18:23 9-strcpy.o

-rw-rw-r — 1 vagrant vagrant 1440 Dec 14 18:23 _putchar.o

[dynamic_library]$

3. Create the library:

Use the following command:

[dynamic_library]$ gcc *.o -shared -o liball.so

[dynamic_library]$

The wildcard * tells the compiler to compile all the .o files into a dynamic library which is specified by the -shared flag. The naming convention for dynamic libraries is such that each shared library name must start with lib and end with .so .Let your imagination run free when considering names for your dynamic libraries.

You create your dynamic library!

You can type this commands to see your master creation:

[dynamic_library]$ ls -la lib*

-rwxrwxr-x 1 vagrant vagrant 13430 Dec 14 13:23 liball.so

[dynamic_library]$ nm -D libholberton.so

0000000000000a90 T _abs

0000000000000aa9 T _atoi

0000000000202048 B __bss_start

w __cxa_finalize

0000000000202048 D _edata

0000000000202050 B _end

00000000000011f8 T _fini

w __gmon_start__

0000000000000900 T _init

0000000000000bd7 T _isalpha

0000000000000c04 T _isdigit

0000000000000c25 T _islower

0000000000000c46 T _isupper

w _ITM_deregisterTMCloneTable

w _ITM_registerTMCloneTable

w _Jv_RegisterClasses

0000000000000c67 T _memcpy

0000000000000caa T _memset

0000000000000ce9 T _putchar

0000000000000d0e T _puts

0000000000000d4a T _strcat

0000000000000dcf T _strchr

0000000000000e21 T _strcmp

0000000000000e89 T _strcpy

0000000000000eeb T _strlen

0000000000000f15 T _strncat

0000000000000fa5 T _strncpy

0000000000001029 T _strpbrk

000000000000109d T _strspn

0000000000001176 T _strstr

U write

[dynamic_library]$

How to use them (Linux only)

Now, We have created a dynamic library and this let us use it by invoking it as part of the linking process when creating a program executable. We can do this easily:

Suppose this is your test_code.c:

[dynamic_library]$ cat test_code.c

#include <stdio.h>



/**

* main - Print the lenght of a string.

*

* Return: Always EXIT_SUCCESS.

*/

int main(void)

{

printf("Number of letters: %d

", _strlen("Dynamic Libraries"));

return (EXIT_SUCCESS);

}

[dynamic_library]$

We use this command to compile the our main file with the dynamic library created:

[dynamic_library]$ gcc -L. test_code.c -lall -o test_code

[dynamic_library]$

L specifies the path to the library .We can use -L. in order to point to the current directory.

Before we run our program, we have to apply this command:

[dynamic_library]$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

[dynamic_library]$

In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories. LD_LIBRARY_PATH tells the dynamic link loader (ld. so, this little program that starts all your applications) where to search for the dynamic shared libraries an application was linked against.

Finally you can run your program:

[dynamic_library]$ ./test_code

Number of letters: 17

[dynamic_library]$

What are the differences between static and dynamic libraries

The best way, always to show diferences is using tables. Here are the key diferences between Dynamic and Static libraries:

This is it! my lovely readers and lovers of C programming languaje. Soon, I will bring more great blogs.

See you!

Daniel Cortes.