Static Libraries vs. Dynamic Libraries in C

Alex Rivera Cruz
8 min readMay 6, 2021

In this publication we mainly explain the process of creation of Static and Dynamic libraries, how to use them and the advantages and disadvantages of each one.

What is a Library in C?

Libraries are known as certain types of files that we can import or include in our program. These files contain the specifications of different functionalities already built and usable that we can add to our program, such as reading from the keyboard or showing something on the screen, among many others.

Why use libraries?

Libraries provide the user the benefit to use a variety of files that can be reused in different programs. For example If we were going to use the same functions in different programs, we will just write it once and reuse it instead of having hundreds of copies of the same function, one in each program.

How libraries work?

Once we have created the library, it can be linked to the file that contains the main function, or entry point, with gcc. Then the code of the functions used in the program will bind to the executable program and it will be ready to run.

What is a Static library?

A static library is a library that is “copied” into our program when we compile it. Once we have the executable of our program, the library is useless (in other words, it is used for other future projects). We could delete it and our program would continue working, since it has a copy of everything it needs. Only that part of the library that is needed is copied. For example, if the library has two functions and our program only calls one, only that function is copied.

How to create a Static library?

In order to put our code in a library, we need to organize it as follows:

  • One or more source files .c with the code of our functions. To see our files run ls -l *.c.
  • One or more .h header files with the types and prototypes of the functions that we want to be able to use. In this case our header file is called holberton.h.

Once we have our code, to get a static library we must perform the following steps:

Get the object files (.o) from all our sources (.c). For this they are compiled with gcc -Wall -pedantic -Werror -Wextra -c *.c. The -c option tells the compiler not to create an executable, but just an object file.

Using ls -l *.o, we can see all the created object files.

To create the library (.a),which we will call as libholbertonschool.a, use the ar command with the following parameters:

ar -rc libholberton.a *.o

The ‘c’ flag tells ar to create the library if it doesn’t already exist. The ‘r’ flag tells it to replace older object files in the library, with the new object files.

We can see the object files inside the library runnig the following command:

ar -t libholberton.a

Now, we need to index the created library using the following command:

ranlib libholberton.a

How to use the Static library?

We will use an example to explain this.

First, we create a program where we call one of the functions of the library.

The program will be called main.c and contain the following code:

#include "holberton.h"int main(void)
{
_puts("Programming is my passion - Lex");
return (0);
}

Note that the chosen function is _puts.

Now we add the library’s name to the command of compilation, using a special flag, normally ‘-l’. Here is an example:

gcc main.c -L. -lholberton -o lexphrase

Note that we omitted the “lib” prefix and the “.a” suffix when mentioning the library on the link command.

Note also the usage of the ‘-L’ flag — this flag tells the linker that libraries might be found in the given directory (‘.’, referring to the current directory)\

We can see that we created a executable called lexphrase, using the command ls lex*.

Executing lexphrase with the command ./lexphrase:

What is a Dynamic library?

A Dynamic or Shared Library is a library that is loaded dynamically at runtime for each application that requires it. Dynamic Linking doesn’t require the code to be copied, it is done by just placing name of the library in the binary file. The actual linking happens when the program is run, when both the binary file and the library are in memory.

How to create a Dynamic library?

In order to put our code in a library, we need to organize it as follows:

  • One or more source files .c with the code of our functions. To see our files run ls -l *.c.
  • One or more .h header files with the types and prototypes of the functions that we want to be able to use. In this case our header file is called holberton.h.

Once we have our code, to get a static library we must perform the following steps:

Compile all the C files in your current directory using the below command:

gcc -c -Wall -Werror -pedantic -fpic *.c

The -c option tells the compiler not to create an executable, but just an object file. The -fpic option makes position independent code (PIC), which is a requirement for dynamic library

Using ls -l *.o, we can see all the created object files.

Now we need to actually turn these object files into a shared library. We will call it libholberton.so:

gcc -shared -o libholberton.so *.o

The -sharedoption creates a shared object(.so) which can be linked with other objects to form an executable.The -ooption allows us to choose the output filename. The .so suffix stands for Shared Object, and this is convention for Dynamic Library names.

We can see the object files inside the library runnig the following command:

nm -D libholberton.so

How to use the Dynamic library?

Since Dynamic Library is linked during runtime, we need to make this file available during runtime. The dynamic linker searches standard paths available in the LD_LIBRARY_PATH and also searches in system cache for dynamic libraries. So our next step is to add our working directory to the LD_LIBRARY_PATH environment variable so that the linker can find our library file. The below command is used for this.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/my_path/

If you do not want to export your current path to LD_LIBRARY_PATH for the dynamic library to work, there is another way to make it work. Move the library to /usr/local/lib because ‘/usr/local/lib’ is already a path specified in the ‘LD_LIBRARY_PATH’ environment variable. Now we need to run ldconfig on the directory you moved it to. This will add our library to a cache which is searched through when a program looks for a shared library:

ldconfig /usr/local/lib

Our dynamic library is ready for use. We can compile and run our program main.c now using our dynamic library libholberton.so

gcc -Wall -pedantic -Werror -Wextra -L. main.c -lholberton -o lexphrase

Note that we omitted the “lib” prefix and the “.so” suffix when mentioning the library on the link command.

Note also the usage of the ‘-L’ flag — this flag tells the linker that libraries might be found in the given directory (‘.’, referring to the current directory)\

We can see that we created a executable called lexphrase, using the command ls lex*.

Executing lexphrase with the command ./lexphrase:

Differences between static and dynamic libraries

  1. Linking time

Static: happens as the last step of the compilation process. After the program is placed in the memory.

Dynamic: shared libraries are added during linking process when executable file and libraries are added to the memory.

2. Means:

Static: Performed by Linker.

Dynamic: Performed by operating system.

3. Size:

Static: much bigger in size, because external programs are built in the executable file.

Dynamic: much smaller, because there is only one copy of dynamic library that is kept in memory.

4. Time:

Static: takes longer to execute, because loading into the memory happens every time while executing.

Dynamic: faster, because shared library code is already in the memory.

5. External file changes:

Static: the executable file will have to be recompiled if any changed were applied to external files.

Dynamic: in the case of shared libraries, no need to recompile the executable.

6. Compatibility:

Static: never has compatibility issue, since all code is in one executable module.

Dynamic: programs are dependent on having a compatible library. If library gets removed from the system or a new compiler released, the dependent program will no longer work.

Advantages and Disadvantages of Dynamic Libraries

  1. It only needs one copy at runtime. It is dependent on the application and the library being closely available to each other.
  2. Multiple running applications use the same library without the need of each file having its own copy.
  3. However, what if the dynamic library becomes corrupt? The executable file may not work because it lives outside of the executable and is vulnerable to breaking.
  4. They hold smaller files.
  5. Dynamic libraries are linked at run-time. It does not require recompilation and relinking when the programmer makes a change.

Advantages and Disadvantages of Static Libraries

  1. Static libraries resist vulnerability because it lives inside the executable file.
  2. The speed at run-time occurs faster because its object code (binary) is in the executable file. Thus, calls made to the functions get executed quicker. Remember, the dynamic library lives outside of the executable, so calls would be made from the outside of the executable.
  3. Changes made to the files and program require relinking and recompilation.
  4. File size is much larger.

--

--