Dynamic Libraries: what are they and what are their benefits? And yes, libraries again.

Gianluca Dorelo
6 min readDec 14, 2020

--

Not really.

Previously, after learning about static libraries, I wrote a blog post to share information about them, how to create them, and how they can help greatly reduce time when writing programs. Since then, I’ve started to learn about a great alternative: dynamic libraries. Here is how they compare to static libraries, including some of the benefits that come with using them instead of static libraries.

Similarly to static libraries, one of the best advantages of using dynamic libraries, is that they save the user a lot of time. Specifically, if I want to use previously made functions in a new program, I can simply create a dynamic or static library based on the c files that include their definitions. With this, I can re-use my library quickly with each new program that I create (saving more and more time). If not for this, I would have to compile each new program with each individual c file or even worse…re-include their definitions in my program.

How Dynamic and Static Libraries Work

Before going into the benefits and drawbacks of dynamic libraries, let’s take a step back and analyze how they work. During the linking phase of compilation, the linker (a software program) combines the program that you’ve written with other files (i.e.: necessary functions) to make your program executable. When using static libraries to provide these necessary functions, their object code is actually injected into the final executable and becomes a part of the application. With dynamic libraries, position-independent code is generated so that that that the library can be referenced at different locations by different programs and the object code itself does not need to be included in the final executable. In addition, the linker will verify that all symbols required by the program are either linked directly to it or in one of the dynamic libraries.

Programs compiled with dynamic libraries execute quite differently than programs compiled with static ones. Programs compiled with dynamic libraries will use a dynamic loader to check which dynamic libraries were linked, loads them in memory, and attaches a copy to the program. Whereas programs compiled with static libraries already include the object code itself.

Distinctive Benefits and Drawbacks of Using Dynamic Libraries

Programs compiled with dynamic libraries need to reference code with the dynamic loader, so they aren’t as quick as programs compiled with static libraries (when executing them). But actually, there are two major benefits to using them. First, since the actual object code is not included in the final executable, the program takes up less space in memory. And secondly, since dynamic libraries are loaded upon runtime, that means you can make changes to them without needing to recompile the programs that use them (for those changes to take effect). This being a huge benefit if you are collaborating with others in the process of creating a program. You will be able to easily share libraries you create with others and not worry about whether they’ve compiled their programs with the latest library updates.

How to create dynamic libraries

Now that we know a bit more about dynamic libraries, how do we create them?

  1. Create a header file which includes the prototypes of the functions you want to include in your library so that they can be properly compiled. You’ll have to use the .h extension to specify that it’s a header file.

2. Copy all the files that you want to be part of your dynamic library into the same directory. Use the cp command for this step:

cp <file(s)> <destination path>

3. Now that you have your header files and the c files you want to use in the same directory, you can compile all the c files into position-independent object code and create the library using the following command:

gcc -g -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libholberton.so

Breaking down the command:

  • The gcc command is used to compile the file.
  • The-Wall -Werror -Wextra -pedantic flags are used to enable compilation warnings (in case you are missing something).
  • The-fPIC flag is used to make the code position-independent.
  • The-c flag is used to halt the compilation at the assembly stage so that only object code is generated (and linking does not kick in).
  • *.c is used to specify that the command is executed upon all files ending in the .c extension (for C files).
  • The-shared flag is used to make a shared object which can later be linked with other objects during runtime to make the “final” executable.
  • Lastly the -o flag allows you to specify the file you want to put the output of the command in.

Our output file will be libholberton.so . The lib prefix and .so suffix specify the “soname” or logical name of the shared object library.

4. Lastly, we can make the library available at runtime by installing it in a standard location. To do that, we can prepend the current working directory (where the library is stored) to the LD_LIBRARY_PATH environmental variable. This will tell the loader to look in the working directory during run time:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

The export command will allow you to set values for the LD_LIBRARY_PATH shell variable. The .: following the equal sign specifies that you want to prepend the current working directory to the shell variable.

The library has been created (libholberton.so)

Note: You can use the ldconfig command to update links and cache the most recently shared libraries. To do so, create a file called local.conf in the /etc/ld.so.conf.d/ directory with the entry /usr/local/lib/ and then run ldconfig.

You can use nm -D libholberton.so to check that all the desired functions have been included.

nm command output

Using Dynamic Libraries

Now that we’ve created a dynamic library, we can use it! After using functions from the library to create a new program, you can make the program executable:

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

The gcc command allows you to compile your program ( 0-main.c ) with the library libholberton.so. Instead of using the library name, you can use the special -l flag, leaving out the prefix and .so suffix. The linker will attach these parts back to the name to create a name of a file to look for. Using the -o flag, we specify that len will be the name of our executable.

Now that we’ve compiled the program, we can use ldd to print the shared object dependencies of the executable and check that our library is one of them:

ldd len

Our library is one of the shared object dependencies as we can see in the above image.

Finally, we can simply run the program by typing in the executable name and prepending it with ./ to specify that it exists in the current working directory:

./len

I hope you find Dynamic Libraries useful in a future!

--

--

Gianluca Dorelo
Gianluca Dorelo

No responses yet