C static libraries

mohamed chedli
4 min readNov 1, 2020

Using A “C” Library In A Program

After we created our archive, we want to use it in a program. This is done by adding the library’s name to the list of object file names given to the linker, using a special flag, normally '-l'. Here is an example:

cc main.o -L. -lutil -o prog

This will create a program using object file "main.o", and any symbols it requires from the "util" static library. Note that we omitted the "lib" prefix and the ".a" suffix when mentioning the library on the link command. The linker attaches these parts back to the name of the library to create a name of a file to look for. Note also the usage of the '-L' flag - this flag tells the linker that libraries might be found in the given directory ('.', refering to the current directory), in addition to the standard locations where the compiler looks for system libraries.

Creating A Static “C” Library Using “ar” and “ranlib”

The basic tool used to create static libraries is a program called 'ar', for 'archiver'. This program can be used to create static libraries (which are actually archive files), modify object files in the static library, list the names of object files in the library, and so on. In order to create a static library, we can use a command like this:

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

This command creates a static library named 'libutil.a' and puts copies of the object files "util_file.o", "util_net.o" and "util_math.o" in it. If the library file already exists, it has the object files added to it, or replaced, if they are newer than those inside the library. The 'c' flag tells ar to create the library if it doesn't already exist. The 'r' flag tells it to replace older object files in the library, with the new object files.

Using A Shared “C” Library — Quirks And Solutions

Using a shared library is done in two steps:

  1. Compile Time — here we need to tell the linker to scan the shared library while building the executable program, so it will be convinced that no symbols are missing. It will not really take the object files from the shared library and insert them into the program.
  2. Run Time — when we run the program, we need to tell the system’s dynamic loader (the process in charge of automatically loading and linking shared libraries into the running process) where to find our shared library.

The compilation part is easy. It is done almost the same as when linking with static libraries:

cc main.o -L. -lutil -o prog

The linker will look for the file 'libutil.so' (-lutil) in the current directory (-L.), and link it to the program, but will not place its object files inside the resulting executable file, 'prog'.

The run-time part is a little trickier. Normally, the system’s dynamic loader looks for shared libraries in some system specified directories (such as /lib, /usr/lib, /usr/X11/lib and so on). When we build a new shared library that is not part of the system, we can use the 'LD_LIBRARY_PATH' environment variable to tell the dynamic loader to look in other directories. The way to do that depends on the type of shell we use ('tcsh' and 'csh', versus 'sh', 'bash', 'ksh' and similar shells), as well as on whether or not 'LD_LIBRARY_PATH' is already defined. To check if you have this variable defined, try:

echo $LD_LIBRARY_PATH

If you get a message such as 'LD_LIBRARY_PATH: Undefined variable.', then it is not defined.

Here is how to define this variable, in all four cases:

  1. ‘tcsh’ or ‘csh’, LD_LIBRARY_PATH is not defined:
  • setenv LD_LIBRARY_PATH /full/path/to/library/directory
  1. ‘tcsh’ or ‘csh’, LD_LIBRARY_PATH already defined:
  • setenv LD_LIBRARY_PATH /full/path/to/library/directory:${LD_LIBRARY_PATH}
  1. ‘sh’, ‘bash’ and similar, LD_LIBRARY_PATH is not defined:
  • LD_LIBRARY_PATH=/full/path/to/library/directory export LD_LIBRARY_PATH
  1. ‘sh’, ‘bash’ and similar, LD_LIBRARY_PATH already defined:
  • LD_LIBRARY_PATH=/full/path/to/library/directory:${LD_LIBRARY_PATH} export LD_LIBRARY_PATH

After you’ve defined LD_LIBRARY_PATH, you can check if the system locates the library properly for a given program linked with this library:

ldd prog

You will get a few lines, each listing a library name on the left, and a full path to the library on the right. If a library is not found in any of the system default directories, or the directories mentioned in 'LD_LIBRARY_PATH', you will get a 'library not found' message. In such a case, verify that you properly defined the path to the directory inside 'LD_LIBRARY_PATH', and fix it, if necessary. If all goes well, you can run your program now like running any other program, and see it role...

--

--