All you need to know about Static and Dynamic Libraries

--

This blog is made for all of those who seek answers regarding shared and dynamic libraries. Since this topic may be a bit confusing at first, my goal is to explain as easy as possible everything related to it. Maybe it should be right to start this blog by introducing what we will cover. These being: What is a Static library, what is a Dynamic library, how do they work, why are they important, how to create and use them among Linux users, how do they differ, and finally what are their advantages and disadvantages.

Before starting I think it’s important to point out at what stage are these libraries taken into account. Every .c file in order to be executed, it must be compiled first; this process of compilation has 4 stages before generating an executable. Our interest relays in the last step called: “Linking”. Here it takes the total amount of object files generated and produces a single executable file, during this process it takes each and every object file and adds some instructions, which are found in the library, and makes your function hopefully do, if there are no errors, what it is said to do. This is why it is important, as C is a small language, it desperately needs libraries to work. This stage, as I like to see it, gives some sort of life to your code because it gives it a purpose and a reason to do something.

Having said that, we can now define what a library is in programming. A library basically is a set of predefined instructions called routines or modules that are stored as object files. A Static library is the result of the linker making a copy of all the used libraries of your program during the compilation process, and saving it in your executable. On the other hand, a Dynamic library doesn’t have the need to copy the libraries in your executable, it only saves the address the where the library is saved in memory. I see this process as if it is created a pointer to the library and our .exe only saves it, this because it actually creates a sort of link between them.

As mentioned, Static libraries store a copy of the libraries used in the result of the compilation process, meaning that it will take up more space on disk and on main memory that what you really need because it creates larger binary files with not nearly the half of what your program needs, if it is more or less advanced program. Which takes me to my next point, each process gets its own copy of the code and the data, instead, in the case of dynamic linking, the code is shared and the data is specific to each process; making them smaller in size.

Also, static libraries during compilation removes the actual code used from the library and uses at when building your program. This means that each time you make a change in your code, you will have to recompile it again and again to see the changes made. On the contrary, when using a dynamic library you can be modify your program and you will not need to recompile because it already created a reference to the library so it works like a kind of symbolic link between them.

It’s important to point out that Static libraries are in fact much faster than dynamic ones, this occurs as a result of no longer having to call more functions from a library. Dynamic linking has to load the the object file each time it is executed, making it a little bit slower, nonetheless this difference is significantly small.

Now being reviewed each kind of library you decide in which cases which one will come handy. Now let’s see how to create each one.

To create a Static library to must first run this command (Linux):

$ gcc -Wall -pedantic -Werror -Wextra -c *.c

Here we are compiling all of the .c files using some flags that basically indicates you errors of different types.

There is a program used to create static libraries called “ar”, which is for “archiver”; according to the manual, this program creates, modifies and extracts from archives. We use the following command to create it:

$ ar -rc libname.a

The r flag means that whatever old object that are in the library will be replaced with the newest ones created. On the other hand, the c flag means that the archive will be created.

When you have done this you must create an index for the library using the “ranlib” command. This program makes a header in the library with the symbols of the object file contents. You should run this command after:

$ ranlib libname.a

After creating the static library to have to compile it with the library, so it can be linked with it and the program can run properly. You also have to take into mind the main file in order to test it. Run this command:

$ gcc main.c -L. -libname.a -o executablename

The -L flag tells the linker that libraries could be found in the working directory. The -l flag searches the specified library, so that it could be taken in mind. The -o option defines the name of the executable, which in this case is “exe”. After this simply execute your executable file with ./executablename.

To create a Dynamic Library to could run the following command (Linux):

$ gcc -fPIC -c *.c

As stated in the manual, the fPIC option: If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on AArch64, m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines. When this flag is set, the macros “__pic__” and “__PIC__” are defined to 2. And the -c option compiles the files but does not link with the libraries.

After this, as .o files were created because it didn’t get to the step where it links, you must enter this command:

gcc -shared -o libshared.so *.o

The -shared option produces a shared object which is linked with other objects to create the executable. The -o option is used to name the output of the compilation, in this case the name of the shared library containing all of the .o files passed during this process.

NOTE: Prefix “lib” is necessary for the library name, or it will not be interpreted correctly.

Here you have already created the library but as you need it to be linkable while running your program you must save it the an environmental variable called “LD_LIBRARY_PATH”, so run the next command in order to nail it:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

Now you just have to compile your .c file as follows:

gcc -L. -lshared main.c

As previously said, the -L flag tells the linker that libraries could be found in the working directory. The -l flag searches the specified library, so that it could be taken in mind.

And that’s pretty much it ! This blog was made as an assignment for Holberton School, a coding school, which I was very excited to do. I really hope this help out all of those people who as me loves to code and wants to be the best at it. Thank you so much for taking your time to read it, I appreciated it a lot.

--

--