Blog — Linux LIBRARIES

What are library files in Linux?

A library is a collection of pre-compiled pieces of code called functions. The library contains common functions and together, they form a package called — a library. Functions are blocks of code that get reused throughout the program. Using the pieces of code again in a program saves time. It keeps the programmer from rewriting the code several times. For programmers, libraries provide reusable functions, data structures, classes and so forth

Libraries were designed to package similar functionality in a single unit. These units could then be shared with other developers and permitted what came to be called modular programming — that is, building programs from modules. Linux supports two types of libraries, each with its own advantages and disadvantages. The static library contains functionality that is bound to a program statically at compile time. This differs from dynamic libraries, which are loaded when an application is loaded and binding occurs at run time.

How Libraries are Used In Linux:

On GNU glibc-based systems, including all Linux systems, starting up an ELF binary executable automatically causes the program loader to be loaded and run. On Linux systems, this loader is named /lib/ld-linux.so.X (where X is a version number). This loader, in turn, finds and loads all other shared libraries used by the program. The list of directories to be searched is stored in the file /etc/ld.so.conf.

If you want to just override a few functions in a library, but keep the rest of the library, you can enter the names of overriding libraries (.o files) in /etc/ld.so.preload; these ``preloading’’ libraries will take precedence over the standard set. This preloading file is typically used for emergency patches; a distribution usually won’t include such a file when delivered.

Searching all of these directories at program start-up would be grossly inefficient, so a caching arrangement is actually used. The program ldconfig(8) by default reads in the file /etc/ld.so.conf, sets up the appropriate symbolic links in the dynamic link directories (so they’ll follow the standard conventions), and then writes a cache to /etc/ld.so.cache that’s then used by other programs. This greatly speeds up access to libraries. The implication is that ldconfig must be run whenever a DLL is added, when a DLL is removed, or when the set of DLL directories changes; running ldconfig is often one of the steps performed by package managers when installing a library. On start-up, then, the dynamic loader actually uses the file /etc/ld.so.cache and then loads the libraries it needs.

Static And Dynamic Libraries in Linux :

Static libraries can be beneficial in small programs where minimal functionality is needed. For programs that require multiple libraries, shared libraries can reduce the memory footprint of the program (both on disk and in memory at run time). This is because multiple programs can use a shared library simultaneously; therefore, only one copy of the library is needed in memory at a time. With a static library, every running program has its own copy of the library.

GNU/Linux provides two ways to deal with shared libraries (each method originating from Sun Solaris). You can dynamically link your program with the shared library and have Linux load the library upon execution (unless it’s already in memory). An alternative is for the program to selectively call functions with the library in a process called dynamic loading. With dynamic loading, a program can load a specific library (unless already loaded), and then call a particular function within that library. This is a common usage pattern in building applications that support plugins.

1. Static Library or Static lib

2. Dynamic or shared libraries

What is a static library and how does it work?

Static library is the library in which all the code to execute the file is in one executable file and this file gets copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable.

The libraries that are locked into a program at compile time are known as static libraries. They are also known as statically-linked libraries and if made up of a set of routines, external functions and variables. After locking into a program at compile time, it is then copied to a target application by a linker, binder or compiler, which in turn produces an object file and a stand-alone executable.

A static library is a file containing a collection of object files (*.o) that are linked into the program during the linking phase of compilation and are not relevant during runtime.

Working Of Static Library

As shown in the diagram above, when a program is compiled, the compiler generates an object file from a source file. After generating the object file, the compiler also invokes the Linker. The role of the linker, in this case, is to copy the code of the library to our object file.

Basically, static libraries are just a collection of object files that are merged by the linker with another object file to form a final executable.

How to create static libraries?

To create a static library, one needs to specify to the compiler, that we want to compile all library codes (*.c) into object files (*.o) without linking.

This can be done using the command → $ gcc -c -Wall -Werror -Wextra *.c

Description of the command:

-c: Compile and assemble, but do not link.

-Wall, -Werro and -Wextra: These aren’t necessary but they are recommended to generate better code.

Note that the “*.c” matches all files in the current working directory with the “.c” extension.

For example, let us take two c files, abc.c , and a header file header.h that contains the prototypes of these functions.

Once we have object file(s), we can now bundle all object files into one static library.

To create a static library or to add additional object files to an existing static library, we have to use the GNU ar(archiver) program.

The command which can be used is → $ ar -rc libxyz.a *.o

This command creates a static library named “libxyz.a” and puts copies of the object files “add.o” and “mul.o” in it. The ‘c’ flag tells ar to create the library if it doesn’t already exist. The ‘r’ flag tells it to insert object files or replace existing object files in the library with the new object files.

After an archive is created or modified, there is a need to index it. This index is later used by the compiler to speed up symbol-lookup inside the library and to make sure that the order of the symbols in the library will not matter during compilation. There are two ways to create or update the index.

The first way to do it is to use the following command → $ ranlib libxyz.a

The second way is to use the following command → $ ar -rcs libxyz.a *.o

Now if we wish to list the names of all the object files present in our library then the following command can be used → ar -t libxyz.a

Using the created static libraries?

After creating the static library (steps given earlier) we need to make use of it in our c programs. To do this we need to add the library’s name to the object file(s) given to the linker. Let’s say we have created a c program hello.c and we want to make use of the functions of the libxyz.a library which we have just created. To do that after writing the code, the final executable program has to be created using the following command → $ gcc hello.c -L. -lxyz -o hello

This will create a program using the object file “hello.o”, and any symbols it requires from the “xyz” static library.

Flags description:

-L : Specifies the path to the given libraries (‘.’ referring to the current directory)

-l : Specifies the library name without the “lib” prefix and the “.a” suffix, because the linker attaches these parts back to the name of the library to create a name of a file to look for.

Dynamic / Shared Libraries

Shared libraries provide modularity to the development environment as the library code can be changed, modified and recompiled without having to re-compile the applications that use this library. For example, for any change in the ‘abc’ library code, no change is required in the programs using ‘abc’ shared library. A shared library (lib) can be accessed through different names from Linux.

Dynamic or shared libraries can further be categorized into:

  • Dynamically linked libraries — here a program is linked with the shared library and the kernel loads the library (in case it’s not in memory) upon execution.
  • Dynamically loaded libraries — the program takes full control by calling functions with the library

Shared Library Naming Conventions

Shared libraries are named in two ways: the library name (a.k.a soname) and a “filename” (absolute path to file which stores library code).

For example, the soname for libc is libc.so.6: where lib is the prefix, c is a descriptive name, so means shared object, and 6 is the version. And its filename is: /lib64/libc.so.6. Note that the soname is actually a symbolic link to the filename.

Locating Shared Libraries in Linux

Shared libraries are loaded by ld.so (or ld.so.x) and ld-linux.so (or ld-linux.so.x) programs, where x is the version. In Linux, /lib/ld-linux.so.x searches and loads all shared libraries used by a program.

A program can call a library using its library name or filename, and a library path stores directories where libraries can be found in the filesystem. By default, libraries are located in /usr/local/lib, /usr/local/lib64, /usr/lib and /usr/lib64; system startup libraries are in /lib and /lib64. Programmers can, however, install libraries in custom locations.

Managing Shared Libraries in Linux

Let us now look at how to deal with shared libraries. To get a list of all shared library dependencies for a binary file, you can use the ldd utility.

Ldd is a Linux command line utility that is used in case a user wants to know the shared library dependencies of an executable or even that of a shared library.

The output of ldd is in the form:

library name => filename (some hexadecimal value)

# ldd /usr/bin/ls

OR

# ldd /bin/ls

Sample Output

linux-vdso.so.1 => (0x00007ffebf9c2000)

libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003b71e00000)

librt.so.1 => /lib64/librt.so.1 (0x0000003b71600000)

libcap.so.2 => /lib64/libcap.so.2 (0x0000003b76a00000)

libacl.so.1 => /lib64/libacl.so.1 (0x0000003b75e00000)

libc.so.6 => /lib64/libc.so.6 (0x0000003b70600000)

libdl.so.2 => /lib64/libdl.so.2 (0x0000003b70a00000)

/lib64/ld-linux-x86–64.so.2 (0x0000561abfc09000)

libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003b70e00000)

libattr.so.1 => /lib64/libattr.so.1 (0x0000003b75600000)

Because shared libraries can exist in many different directories, searching through all of these directories when a program is launched would be greatly inefficient: which is one of the likely disadvantages of dynamic libraries. Therefore a mechanism of caching employed, performed by the program ldconfig.

By default, ldconfig reads the content of /etc/ld.so.conf, creates the appropriate symbolic links in the dynamic link directories, and then writes a cache to /etc/ld.so.cache which is then easily used by other programs.

This is very important especially when you have just installed new shared libraries or created your own, or created new library directories. You need to run ldconfig command to effect the changes.

Advantages and Disadvantages of Dynamic Libraries

  1. It only needs one copy at runtime. It is dependent on the application and the library being closely available to each other.
  2. Multiple running applications use the same library without the need of each file having its own copy.
  3. However, what if the dynamic library becomes corrupt? The executable file may not work because it lives outside of the executable and is vulnerable to breaking.
  4. They hold smaller files.
  5. Dynamic libraries are linked at run-time. It does not require recompilation and relinking when the programmer makes a change.

Advantages and Disadvantages of Static Libraries

  1. Static libraries resist vulnerability because it lives inside the executable file.
  2. The speed at run-time occurs faster because its object code (binary) is in the executable file. Thus, calls made to the functions get executed quicker. Remember, the dynamic library lives outside of the executable, so calls would be made from the outside of the executable.
  3. Changes made to the files and program require relinking and recompilation.
  4. File size is much larger.

References :

  1. https://www.tecmint.com/understanding-shared-libraries-in-linux/
  2. https://www.tutorialspoint.com/understanding-a-so-and-la-library-files-in-linux
  3. https://opensource.com/article/20/6/linux-libraries
  4. https://www.ibm.com/docs/en/aix/7.1?topic=techniques-when-use-dynamic-linking-static-linking
  5. https://dev.to/iamkhalil42/all-you-need-to-know-about-c-static-libraries-1o0b
  6. https://medium.com/swlh/linux-basics-static-libraries-vs-dynamic-libraries-a7bcf8157779
  7. https://techadminblog.com/linux-library-files/
  8. https://amir.rachum.com/blog/2016/09/17/shared-libraries/

If you liked this blog and it helped you in knowing some of these concept, then please do share this with your friends and comment down and let us know what you are think about it!

Thank You :)

Writers:

Rahul Kanade

Shubham Kasar

Adarsh Londhe

Kshitij Magare

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Static vs Dynamic libraries in C!

Then: Woodworker, Now: Junior Full Stack Developer

Part2 — OpenSource Widgets to Power GitHub Profile README

Winning the hackathon accidentally

The definitive guide on compiling and linking Boost C++ libraries for Visual Studio projects

Raise your hand if you want to quit drinking coffee.

Test-Driven Development done right

Multi-Step Form with Flutter Bloc and Stepper Widget

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
SHUBHAM KASAR

SHUBHAM KASAR

More from Medium

Containers In Kubernetes — Day 08

Ansible Role to Configure K8S Multi- Node Cluster over AWS Cloud

Serve up Images with CloudFront

HTB Monteverde Machine Walkthrough.