Differences between dynamic libraries vs static libraries

Facundo Diaz
7 min readDec 14, 2020

Why use libraries?

Software is made up of functions. Functions are kind of like mini-programs that can be “called” by another program to perform some type of action such as a computation or modification of input.

Here’s a C program that uses a function called sum() to add two numbers together and stores the output in a variable called “result”:

int main(void)
{
int x = 5;
int y = 8;
int result; result = sum(x, y);
return (0);
}

In order for this program to compile and become usable, the compiler must know what and where the function sum() is.

A programmer could define and write the function sum() above the main function so the compiler finds it right away, within the program itself. It could look something like this:

int sum(int a, int b)
{
return (a + b);
}int main(void)
{
int x = 5;
int y = 8;
int result; result = sum(x, y);
return (0);
}

sum() is a very basic function, it just adds two variables and returns the result. As functions get more and more complex, they can become very long and make the main program hard to read. In addition, programs usually call numerous functions, so hard-coding functions above main() can get very messy.

This is where static libraries come in. You can think of a library as a collection of books. Each book is a function that can be read by anyone who has access to the library. Static libraries help keep programs clean and concise for humans but they do have some drawbacks, which we will touch on later.

How they work

Static libraries, also called “archives”, are just collections of object files that contain functions. All the functions within the library are organized and indexed with a symbol and address, kind of like a table of contents, which makes it easier to find what you’re looking for.

Static libraries are joined to the main module of a program during the linking stage of compilation before creating the executable file. After a successful link of a static library to the main module of a program, the executable file will contain both the main program and the library.

How to create them

Static libraries are created using some type of archiving software, such as ar. ar takes one or more object files (that end in .o), zips them up, and generates an archive file (ends in .a) — This is our “static library”.

Before using ar, we must first have some object files to give to it. Perhaps we’ve written some functions in C that we want to include in our library. We can use the -c option with the GNU compiler (gcc) to stop the compiling process after the assembling stage, translating our files from .c to .o.

$ gcc -c sum.c   // produces a sum.o object file

Now that we have the object file(s), we can archive them and make a static library using ar.

$ ar -rc libforme.a sum.o

The command above will create a static library called “libforme.a”. Inside of it will be our sum() function that has been translated to an object file via the gcc command earlier.

Note: the -rc options create the archive without a warning and replaces any pre-existing object files in the library with the same name.

Some archivers automatically organize and index the library, but in case indexing didn’t occur, we can use a command called ranlib to generate and store an index in the archive.

The index lists each symbol defined by a member of an archive that is a relocatable object file. To see a list of the symbols from object files we can use a command called nm.

$ nm libforme.a// sample outputsum.o:000000000000002e T sum

So now that we’ve created object files, zipped them in up an library and indexed it, we are ready to use our library.

How to use them

Let’s say we want to compile our C program from the beginning of this post; the one that uses sum() to store the value of two numbers:

int main(void)
{
int x = 5;
int y = 8;
int result; result = sum(x, y);
return (0);
}

When we try to compile the program we might see an error like this:

gcc my_program.c// oops... ///tmp/ccGLAk66.o: In function `main':my_program.c:(.text+0x26): undefined reference to `sum'collect2: error: ld returned 1 exit status

The compiler doesn’t know what sum is. We need to tell it to look in our library:

gcc my_program.c -L. -lforme -o my_program

Let’s break that down:

  • -L says “look in directory for library files”
  • . (the dot after ‘L’) represents the current working directory
  • -l says “link with this library file”
  • forme is the name of our library. Note that we omitted the “lib” prefix and “.a” extension. The linker attaches these parts back to the name of the library to create a name of a file to look for.
  • -o my_program says “name the executable file my_program”

If everything worked out, the result will be an executable file called my_program that uses the sum() function that is contained in the libforme.a static library.

DIFFERENCES

Not having to rewrite the code (or copy-paste).

We will save the time of compiling each time that code that is already compiled. In addition, we already know that while we make a program, we test and correct, it is necessary to compile between many and “more many” times.
The already compiled code will be tested and reliable. Not the first times, but when we have already used it in 200 different programs and we have corrected the errors.

HOW DOES THE SYSTEM FIND THE LIBRARIES?

LD_LIBRARY_PATH: It is one of the places where the operating system looks for dynamic libraries.

GCC

GCC is an integrated compiler of the GNU project for C, C ++, Objective C, and Fortran; it is capable of receiving a source program in any of these languages ​​and generating a binary executable program in the language of the machine where it has to run.
The acronym GCC stands for “GNU Compiler Collection”. Originally it stood for “GNU C Compiler”; GCC is still used to designate a C build. G ++ refers to a C ++ build.

Syntax.
gcc [option | archive ] …
g ++ [option | archive ] …
Options are preceded by a hyphen, as is common in UNIX, but the options themselves can be multiple letters; Multiple options cannot be grouped after the same script. Some options then require a file or directory name, others do not. Finally, several file names can be given to include in the compilation process.

Examples
gcc hello.c
compile the C program hello.c, generate an executable file a.out.
gcc -o hello hello.c
compile the C program hello.c, generate an executable hello file.
g ++ -o hello hello.cpp
compile the program into C ++ hello.c, generate an executable hello file.
gcc -c hello.c
It does not generate the executable, but rather the object code, in the hello.o file. If you don’t specify a name for the object file, use the filename in C and change the extension to .o.
gcc -c -o object.o hello.c
generates the object code indicating the file name.
g ++ -c hello.cpp
same for a C ++ program.
g ++ -o ~ / bin / hello hello.cpp
generates the hello executable in the bin subdirectory of the user’s home directory.
g ++ -L / lib -L / usr / lib hello.cpp
indicates two directories where libraries are to be searched. The -L option must be repeated for each library search directory.
g ++ -I / usr / include hello.cpp
indicates a directory to search for header files (extension .h).

NM

The nm command, present in the latest versions of Unix and similar operating systems, is used to aid in debugging when examining binary files, including libraries, object modules, and executables.

LDD

ldd (List Dynamic Dependencies) is a * nix utility that prints the shared libraries required by each program or shared library specified on the command line.It was developed by Roland McGrath and Ulrich Drepper. If some shared library is missing for any program, that program won’t come up.

LDCONFIG

The ldconfig Linux command creates the necessary links and cache (for use by the run-time linker, ld.so) to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so. conf, and in the trusted directories (/ usr / lib and / lib). It checks the header and file names of the libraries it encounters when determining which versions should have their links updated; it ignores symbolic links when scanning for libraries.

Ldconfig will attempt to deduce the type of ELF libs (ie. Libc 5.x or libc 6.x (glibc)) based on what C libraries if any the library was linked against, therefore when making dynamic libraries, it is wise to explicitly link against libc (use -lc).

Ldconfig should normally be run by the super-user as it may require write permission on some root owned directories and files. If you use -r option to change the root directory, you don’t have to be super-user as long as you have sufficient rights to that directory tree.

RANLIB

ranlib command in Linux is used to generate index to archive. ranlib generates an index to the contents of an archive and it will be stored in the archive. The index lists each symbol defined by a member of an archive which is simply relocatable object file. You may use nm -s or nm –print-armap to list all of this index. An archive with such an index speeds up the linking to the library and allows routines in the library to call each other without regard to their placement in the archive. The GNU ranlib program is another form of GNU ar; running ranlib is completely equivalent to running ar -s.

Syntax:

ranlib [ — plugin name] [-DhHvVt] archive

AR

ar command is used to create, modify and extract the files from the archives. An archive is a collection of other files having a particular structure from which the individual files can be extracted. Individual files are termed as the members of the archive.

Syntax:

ar [OPTIONS] archive_name member_files

This post was created by Facundo Diaz by Holberton School

--

--