Libraries in C

Andrew
4 min readFeb 12, 2018

--

Libraries are collections of named functions that are referenced to during the linking phase of compilation. Libraries are kept in .a or .so formats in Linux and are used as a more optimized alternative to using a group of object files. There is also the added benefit of portability as the object files are already wrapped up into an executable so there is no need to rewrite it. Such libraries are known to come in two flavors: static and dynamic.

What is a Static Library?

Static libraries are just archive files of object files with a list of addresses for each program. Such files are named with the prefix “lib” and the suffix “.a”. During the linking phase of compilation, the entirety of the library is included in the final executable file. This means that if 3 different programs linked to the same static library then the resultant executable for each program will contain the full copy of the static library. This can lead to rather large file sizes. Of course, this also means that the executable is now completely self-sufficient with no dependencies and the coder can be sure the right library is being used.

On the other hand, there are dynamic libraries. These libraries aren’t included in the final executable but are rather loaded into memory at runtime prior to resolving symbols. This means that many programs can reference to this shared file while keeping the program small and avoid the need to load the library for every program that needs its symbols.

How to create static libraries

In order to create a static library, you will have to start with making object files of the programs to be included in the library.

gcc -c *.c

This command creates all the object files from every c source file within the current directory. Once created, the ar command is needed to make the library file itself.

ar -rc libstat.a *.o

The r flag instructs the command to replace older object files int he library with the new object files. The c flag instructs the command to make the library if it doesn’t already exist.

Now that a new library exists, it must be indexed to help the compiler speed up symbol lookup within the library. This is especially useful with large libraries that can have thousands of symbols. The command for indexing a library is simply ranlib.

ranlib libstat.a

To check the contents of the library, we can use the ar command with the -t flag.

The nm command creates a detailed list of the symbols included in the library.

How to use the static library

Using a static library is very straightforward as it only requires the gcc command. For now, I will use:

gcc main.c -L. -lstat -o main

As you noticed by now, there are two different l flags utilized. These flags help the compiler locate the library. The big L tells the compiler which directories to look in. In this case I listed the current directory using the . but the full path name can also work. The small l flag tells the compiler the name of the library. When using the l flag, be sure to remove the prefix and file extension.

Time to wrap it up

Long story short, static libraries are nice to have as they are not required at run time so distribution of the final program is easier. Since the library is essentially baked into the program, bug fixes will generally be harder to go around as the entire program will have to be recompiled and redistributed as well as any other program that uses the same static library. This is where dynamic libraries shine. Dynamic libraries are loaded into memory at runtime prior to resolving symbols. This means that you can swap out dynamic libraries at any time when the program is closed as long as the symbols are left intact. Dynamic libraries also only link whatever is needed so the main takeaway is to use static libraries when the program absolutely need certain object codes.

--

--