Dependency Hell is Coming

Two months ago, I wrote about static libraries in Linux and reasons to use them. In today’s article, I will introduce the concept of dynamic libraries in Linux and aim to cover the following:

  • why, in general, C libraries are used
  • differences between static and dynamic C libraries
  • advantages and drawbacks to each type of library
  • how dynamic C libraries work
  • how to create and use dynamic C libraries in Linux

Why use C libraries?

Creating a library allows users to group together multiple compiled object code files into one file. This allows a user to share functions with multiple applications. Libraries can be either static or dynamic.

Difference between static and dynamic C libraries

In Linux, static libraries are also known as archive libraries. In my previous post, I drew a comparison between static libraries and encyclopedias. An encyclopedia represents a snapshot of knowledge that at one point in time which cannot be updated without replacing the entire library of books. To further draw out this metaphor, if encyclopedias are static libraries, then wikipedia is a dynamic library, able to be updated at any point and at various levels — sitewide, subject level or page specific.

Advantages and drawbacks to each type of library

Static library

Advantages

  • The most significant is that the application can be certain that all its libraries are present and that they are the correct version. This avoids dependency problems, known colloquially as dependency hell.
  • Static linking can also allow the application to be contained in a single executable file, simplifying distribution and installation.
  • You only need to include those parts of the library that are directly and indirectly referenced by the target executable. With dynamic libraries, the entire library is loaded, as it is not known in advance which functions will be invoked by applications.

Disadvantages

  • Since applications will be contained in a single file, you ultimately have a larger file size and will need to download the entire file each time you update programs — as you can imagine, this would be quite the hassle to deal with in distributing updates to programs.

Dynamic library

Advantages

  • Efficiency — several programs can share the same object code, which saves storage space as well as physical memory during execution.
  • When updating programs, instead of downloading the entire application file, only the new dynamic libraries need to be downloaded and the old ones removed.

Disadvantages

  • DLL Hell — as discussed above, usage of dynamic libraries can lead to dependency hell. In short, this means that programs assuming that a specific dynamic library is available would not work if that library is not installed or incompatible with that version of the program.
Thank you Google image search
  • Performance lag — with older machines, there may be a slight lag in speed between static libraries and dynamic libraries.

How dynamic C libraries work

Dynamically linked shared object libraries (.so) can be used in two ways:

  1. Dynamically linked at run time but statically aware. The libraries must be available during compile/link phase. The shared objects are not included into the executable component but are tied to the execution.
  2. Dynamically loaded/unloaded and linked during execution (i.e. browser plug-in) using the dynamic linking loader system functions.

How to create and use dynamic C libraries in Linux

There are two steps in creating a dynamic library:

1. Create object code

Once you are in the working directory that you want to create your dynamic library from, run gcc with the following flags.

gcc -Wall -fPIC -c *.c
  • -Wall include warnings. See man page for warnings specified.
  • -fPIC: Compiler directive to output position independent code, a characteristic required by shared libraries. Also see “-fpic”.
  • -c generates object code from .c files
Step 1 — generate object code!

2. Create library

Once object code is generated, making your dynamic library is next!

gcc -shared -Wl,-soname,mydynamiclibrary.so -o mydynamiclibrary.so *.o
  • -shared: Produce a shared object which can then be linked with other objects to form an executable.
  • -Wl,options: Pass options to linker. In example below the options to be passed on to the linker are: -soname mydynamiclibrary.so. The name passed with the “-o” option is passed to gcc.
  • -o: Output of operation. In this case the name of the shared object to be output will be mydynamiclibrary.so

Once you’ve created your library you can list symbols from object files by running nm . Use option -D in order to list dynamic symbols.

nm -D in action

From there, you can compile files with your new library. This example is with a different library named libholberton — notice that in compilation, the library is called as lholberton.

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

To print shared library dependencies, something unique to dynamic libraries, run ldd on your program.

% ldd len 
linux-vdso.so.1 => (0x00007fff5d1d2000)
libholberton.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f74c6bb9000)
/lib64/ld-linux-x86-64.so.2 (0x0000556be5b82000)

If “not found” is returned as it is in line 3 above, then you need to update your environmental variable LD_LIBRARY_PATH.

% export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
% ldd len
linux-vdso.so.1 => (0x00007fff41ae9000)
libholberton.so => ./libholberton.so (0x00007fd4bf2d9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd4beef6000)
/lib64/ld-linux-x86-64.so.2 (0x0000557566402000)
% ./len 
9
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.