DEV Community

Cover image for C - Static libraries
Haile Melaku
Haile Melaku

Posted on

C - Static libraries

Up until now we wore working with smaller program's,but when we create a very large program we are faced with some problem like

  • Increase in overall time of compilation and linking.

  • polluting out makefile.

  • polluting out directory where we placed the source files.

when we are faced with this problem's, we might look of a way of combining the source code into small units of related files.


#What Is A "C" Library

A library is a file containing several object files,used in the linking Phase of a program.

Why use Library's

  • Library is indexed so that it is easy to find functions, variables and others

  • Linking a program whose object files are ordered in libraries is faster than linking a program whose object.

  • Speeds up linking

We can create two types of library's

  • static libraries

  • shared (or dynamic) libraries

static libraries
Are object files that are linked into the program during the linking phase of compilation and are not used during the runtime.

During the creation of the executable file static library's are copied in the source code,so we can run the program only with the executable file.

The drawback of static linking is the size of the file will increase, maintaining update of the app is hard as the create file has everything it needs to run on it's own and we need to recompile every time we use the program.

Static library in

  • Windows have a .lib (library) extension

  • Linux have a .a (Archive) extension

Shared libraries (dynamic libraries)
Are object files that are linked into the program both during the linking phase of compilation and during the runtime.

During the compile time of the program the shared libraries are used to verifies that all the functions, variables and others required by the program, are either linked into the program, or in one of its shared libraries.

During the runtime of the program the shared libraries are loaded to memory by the program.

When we create the executable of a file the address of the shared library are stored in the final executable file.

Some drawback of dynamic linking is launching the program is slightly slower and when we recompile the program we face a problem which is the copy of the previous library is already stored in memory.

Dynamic library solves some of the problem's with static inking such as size and need for compilation.

Shard library in

  • Windows have a .dll (dynamic link library) extension

  • Linux have a .so (shard object) extension


#Creating A Static "C" Library

We can create a static library using a program called 'ar', for 'archiver'.
To create a static library use the command:

ar rc static_lib.a factorial.o mult.o 
Enter fullscreen mode Exit fullscreen mode

This command creates a static library named static_lib.a using two Object file's factorial.o and mult.o,r tells the archiver to replace older object files in the library, with the new object files and c tells the archiver to create the library if it doesn't already exist.

To create an object file form a c file use the command

gcc -g -O -c factorial.c
gcc -g -O -c mult.c
Enter fullscreen mode Exit fullscreen mode

Now we have created the static library we need to index it.
Index is used to by the compiler to speed up symbol-lookup (like functions, variable and so on) inside the library.

The command used to create or update the index is called 'ranlib' and is used like

ranlib static_lib.a
Enter fullscreen mode Exit fullscreen mode

For more info use the commands man ar and man ranlib


#Using A "C" Library In A Program

Up to now we learned about creating a static library and now we want to use this library in our program.

gcc main.c static_lib.a
Enter fullscreen mode Exit fullscreen mode

In this example we will compile the main.c program while requiring the static_lib.a library.


#Creating A Shared "C" Library

shared(Dynamic) library has the same process of creation as static library, but it differs in two ways

  • When creating the object file for the library we have to use the flags -fPIC or -fpic which are "Position Independent Code"(PIC) to use relative address of the memory, because many different programs may load the program into different location of the memory.
gcc -fPIC -c factorial.c
gcc -fPIC -c mult.c
Enter fullscreen mode Exit fullscreen mode
  • Unlike static library a shared library is not an archive file,So it has to be specifically tailored to the operating system it is being created. we could use the -G flag or -shared flag depending on the compiler.
gcc -shared shared_lib.so factorial.o mult.o
Enter fullscreen mode Exit fullscreen mode

In this example we use the flag -shared to create the shared library for this library named shared_lib.so using the object files factorial.o and mult.o,By looking at the extension .os we can conclude that this library run on linux.


#Using A Shared "C" Library

As we have mentioned we use the shared library in two cases:

  • Compile Time - tells the linker to scan the shared library while building the executable program. It's done the same as static library
gcc main.c shared_lib.os
Enter fullscreen mode Exit fullscreen mode
  • Run Time - tells the loader where to find our shared library. Using the shared library is a little trickier when used in run time. we can use the 'LD_LIBRARY_PATH' environment variable to tell the loader to look in other directories. In bash
LD_LIBRARY_PATH=/full/path/to/library/directory
export LD_LIBRARY_PATH
Enter fullscreen mode Exit fullscreen mode

#Loading A Shared Library Using dlopen()

To load and open a shared(dynamic) library we use the dlopen() function.

Example

#include <dlfcn.h>      /* defines dlopen(), etc.       */

int main(void)
{
void* lib_handle;       /* handle of the opened library */

lib_handle = dlopen("/full/path/to/library", RTLD_LAZY);
if (!lib_handle) {
    fprintf(stderr, "Error during dlopen(): %s\n", dlerror());
    exit(1);
}
}
Enter fullscreen mode Exit fullscreen mode

dlopen() takes two parameters,first one is the full path to shared library and the second one is used to check if the symbols of the library need to be checked immediately(RTLD_LOCAL), or only when used(RTLD_LAZY).

Top comments (0)