Dynamic and Static libraries in Linux
Let’s continue getting the most out of some of those portable cleaver solutions (functions) we find to solve problems when coding: Let’s create a Dynamic Library.
On a previous article (see below) I shared about the different types of libraries in Linux, but only went deep into Static libraries, its pros and cons, how to create and use them. Now, let’s dive into dynamic libraries and find out what are their main differences, so we can get a better idea of what and when to use each.
it is important to remember the basic definition of library: a set of C programs (like functions) we have compiled into object (.o) and put together into a kind of executable file that instead of running directly, its functions are called with parameters from our executable.
When compilating in C, libraries are added at the linking step (click here for more info about compilation process in C), and here comes the main difference between Static and Dynamic Libraries in Linux: when we use static libraries, the main code, all the functions used and everything inside the library is copied into the executable file, instead, if using dynamic libraries, the library and all its content is stored in a separated file, located in the PATH for libraries of our system or a location defined by us, and only its address is copied into the executable file, creating a link between it and the library, this way, when a function stored in the library is called from a the exe file, it will look for the library address in the memory, enter that library and look for the requested function.
With the aforementioned information, lets see some pros and cons of each one.
- Faster execution: since all the code, and libraries are within the same executable file, its execution time is shorter than the files using dynamic libraries, this is more representative in big files with a considerable amount of functions and calls.
- Portability: again, having all the needed code in one file, makes it easier to port the program from system to system.
- Bigger files: due to its “all included” nature, using static libraries will result in bigger files.
- Limited or more difficult updating process: We have to go through all the library creation and program compilation process every time we do a modification, update or any change to any of the functions contained in the library
- Smaller files: Only the main program code is in the executable file.
- Flawless updates: If we do any modification on any of the functions in the library, there is no need to compile the main program again, only the library, it is because when calling the function from the executable file, the system will look for where the link (address) points to, which should be the latest version of the library.
- Not as easy to carry as static libraries: The library and the executable file are two separated files, and as such we have to carry both and export the library to the its PATH in every system we want to use it.
- Longer execution times: Calling and getting the functions in the library implies a search in the memory address it was allocated, it means additional processes and waiting times, which may be representative in big files with a considerable variety of functions and calls.
So, an static library is kind of carrying with you all the time, all the tools your are going to need to do a lot of different tasks during a day, you go safe you have all you need at hand, but you will need a bigger bag and, if your duties changes every day, you must unpack your tools, add the new ones, dismiss the useless ones and pack again.
A Dynamic library is more like leaving all the tools in a known near place, check one specific task and get only the ones you are going to need for it, repeat this for each task, you go lighter, your tasks may change and you just get the new tools you need, but you have go back and forward multiple times, as many times as tasks you have.
Creating a Dynamic Library
Lets create a dynamic library called my_library.
First off, the tools: It is advisable to get all (and only) the C files you are going to use in you library and the Header file listing them (don’t forget to include the macros ifndef<HEADERFILE>_H and define <HEADERFILE>_H at the top and bottom, this way the header files is only defined once and not every time it is called.)
$ gcc *.c -c -fPIC
This command tells C to compile (gcc) each and all our ‘.c’ files(*- more on wildcards here) in the current directory into object (-c) files (.o extension).
-fPIC (Position Independent Code) flag is necessary to ensures that the code is position-independent, this is, the generated machine code is not dependent on being located at a specific address in order to work
If you want to specify the files to be compiled, type:
$ gcc -c your_file_name.c -fPIC
Now that we have all our .c files compiled into object files (.o), we can proceed to create tour dynamic library. type:
$ gcc *.o -shared — o libmy_library.so
We give it a name (my_library in this example), add the “lib” prefix to it (requirement), and end it with the .so extension (shared object).
Lastly, it is necessary to export the path of the library, this will let programs know where to look for it if called, this is done with the following command:
or you can specify the path of your library like this:
We have successfully created our library and exported it, now we can use it.
Using a dynamic library.
As we did with our static library article, when compiling it is necessary to specify that we are going to use a dynamic library.
The compilation command line should be as follows:
gcc -L my_main_file.c -lholberton -o my_main_file
The -L flag, specifies the path to the library, in this example, the path is the current working directory, so it is not necessary to type it.
If it were located somewhere else, the path should look somewhat like this, depending on the path location:
The -l flag specifies the name of the library, we don’t need to provide the prefix (lib) and extension (.so), the compiler solves it.
How to check what is inside a dynamic library?
If you want to know what functions or programs are contained inside a dynamic library, just type:
nm -D liblibrary_name.so
You can also check the dependencies of a library with the ldd command:
(More on dependancies here)
Recapping what we have done and learned so far to create a dynamic library:
- Gather the functions you want to add to a library.
- Compile all the .c files into object files (
$ gcc *.c -c fPIC)
- Create the static library (
$ gcc *.o -shared — o libmy_library.so)
- Export the path to the library
Hope it has been helpful!.