C Libraries, what are they and how to use them

Paul Manot
4 min readOct 10, 2020

A library is just a file packaging some common functionality. In other words it is just a piece of code, i.e functions and variables, that you’ve grouped together because you thought it a good idea to reuse it for more then one application. Just like a book in a normal library. you need to learn something about a precise subject you go to pick a book about this topic. Note that libraries are not executable files and therefore cannot do much on their own. Indeed you need to find a way to add them to some existing code in order to use their functionalities.

You have two types of libraries (two ways of adding code), static and dynamic (also called shared) libraries.

Static Libraries

Static libraries are added at compile time, meaning that the code in the library is added to the existing code during compilation. It is simply copied and pasted at the top of the existing code in order to be used. Not all the code in the library but just what’s needed by the program. Imagine you have a library called libmymath.a and you have two functions on it, add and sub . If you are only using add, the code of sub will never be copied to the final application. Therefore the code of add is part of the newly created application.

How to create a static library?

First you need to package you c files containing your functions into object files (binaries) by running the following gcc command.

$ gcc -c myfile.c

And the result is an object file called myfile.o you can change the name of the destination file as per the following naming convention like so.

$ gcc -c myfile.c -o util_myfile.o

Once you’ve turned all of your functionalities into .o files you can create your static library using a program called ar for archiver. Note that it is also a convention to prepend your filename with the term lib .

$ ar rc libutil.a util_file.o util_net.o util_math.o

How to use your static library?

The resulting .a file can then be added to your application.

$ gcc main.o -L . -l util -o prog

Note that we need to use the object version of the main application file not an already fully compiled file and linking -l the library called util in the current directory -L . . Also note that we need to strip util from its prefix lib and extension .a .

To speed up the look up process you can index your library by using another utility called ranlib on your newly created library.

Dynamic Libraries

Unlike static libraries dynamic libraries are not package with the application code and are requested at run time. Therefore they can be shared between different applications.

How to create a dynamic library?

The first step is very similar to a static library but with a key difference. Same as for a static library you need to package your functionality as object files but you give them the -fpic flag to give them a relative address in memory. This is needed because the library will be used by more then one file as it is shared.

$ gcc -fpic -c util_myfile.c

Also note that a shared library is not an archive. Because it is shared it has a different format and can be create with gcc directly using the -shared flag.

gcc -shared libutil.so util_myfile.o util_myotherfile.o

Since the shared library is not an archive it doesn’t have a .a extension but a .so one.

How to use your dynamic library?

The next step is the same as for the static library

gcc main.o -L. -lutil -o prog

but you’ve linked a different type of library which as we’ve mentioned before won’t get added to the code at compilation time. Therefore you need to specify the path to the library in order for it to be used by different applications.

$ LD_LIBRARY_PATH=/full/path/to/library/directory
$ export LD_LIBRARY_PATH

Summary of static vs dynamic libraries which should you use?

Well it all depends on the use case. Static and Dynamic have their pros and cons.

Static

pros:

  • Executables can load faster, because symbol resolution already took place at compile time.
  • No dependencies, all the code needed is packed with the application.

cons:

  • Executables can get really big therefore slow.
  • Executables cannot be updated without relinking.

Dynamic

pros:

  • If an .so is already loaded, the executable may load faster, because it is a smaller file.
  • The code in the library only need to be loaded once (interesting when shared across lots of executables)
  • Executables can be updated without relinking.

cons:

  • All library must be loaded even if a small part of it is required
  • Executables can be broken if the library is being updated.

--

--