Difference Between .a and .so files


Overview

A programmer may want to write three different programs. However, he realizes that some of the functionality needed for each program could be shared among them. Therefore, he decides to create a library containing these shared features.

A library is basically a collection of code and data that other people can use. On Linux, archives (located at the.a file extension) contain compiled code, whereas shared objects (.so files) contain interpreted code.

Here, we’ll examine how software runs under Linux and the purposes of the library and archive files. We’ll also see some examples of how we can create these files for our own applications. We will use the GCC compiler and the GNU ar utility to accomplish this task.

How Programs Run Under Linux

Most Linux systems have probably encountered the /lib and /user/lib directories. These are the directories that contain all the common functions that are needed by the programs installed on the computer. A convention states that a library name begins with "lib" and the extension indicates the type of the file −

.a — stands for “archive”
.so — stands for “shared object”

A program may depend on multiple shared objects. Manually downloading and unzipping the shared object files can be cumbersome. We need a package manager so that we can calculate and determine the dependencies before installing the software itself.

When we run the application, it will look for any required dependencies in the /lib and /share folders. If the required dependencies aren't installed, the program won't run.

Program Libraries

Libraries provide functions for performing specific tasks. For instance, multiple applications may require the use of complex number calculations. A good example of a function provided by a library is the GNU C Standard Libray (libc), which is linked to our applications when we compile them using the gcc compiler.

Static Libraries

A traditional static library is a collection of source files compiled into an archive file (e.g.,.a) that can be used by a compiler during compilation. When linking against such a library, the linker does not require any additional information about the contents of the library; instead, it simply takes the archive file and places it somewhere within the final application binary. In contrast, dynamic libraries are loaded dynamically at runtime. They are typically shared objects (.so), although they may also be archives (.a). Dynamic libraries allow applications to share data without having to recompile them every single release.

Static libraries usually end with the .a extension — for example, glibc.a.

Shared Libraries

To address the problem of large executables, programmers often turn to shared libraries. Dynamic library files are also known as shared library files. These statically linked files are linked into an application when it runs for the first time.

Shared libraries usually end in.so (for shared object) − for instance, libboost_filesystem.so. Unlike static libraries, programs referencing dynamic libraries won't include their corresponding objects when they're built into an executable. So, we get smaller executables.

When there are multiple applications referencing the same shared library, then the library has one copy that can be used by all of them at once. It’s safe to say that Linux is one of the most important foundations of modern computing. Let's take a look at the xorg folder −

$ ls -halF /usr/bin/xorg
-rwxr-xr-x 1 root root 95K Apr 13 20:12 libexa.so*
-rwxr-xr-x 1 root root 23K Apr 13 20:12 libfbdevhw.so*
-rwxr-xr-x 1 root root 111K Apr 13 20:12 libfb.so*
-rwxr-xr-x 1 root root 213K Apr 13 20:12 libglamoregl.so*
-rwxr-xr-x 1 root root 143K Apr 13 20:12 libint10.so*
-rwxr-xr-x 1 root root 15K Apr 13 20:12 libshadowfb.so*
-rwxr-xr-x 1 root root 39K Apr 13 20:12 libshadow.so*

We can see that xorg uses the listed shared library files. Those files, in turn, can be utilized by other programs such as dwm.

Building .a or Static Library

To illustrate this example, we will need GCC to be able to run the program. If we want to use GCC to create an executable file from our C programs, we would issue the following command −

$ gcc -Wall -c *.c

We need to make certain that we're at the bottom of the folder structure. The -W flag causes the compiler to print out all the warnings it finds. The * character in the *.c argument instructs the compiler to compile all.c files. When you issue the following commands, the compiler will compile each.cpp file into an object file. We then get all the required.o file(s) that we will use to create our own library.

After creating an archive, we're now ready to extract the object code into a library. We'll use the ar utility, which comes with GNU Binutils.

$ ar -cvq libfile.a *.o

To create an archive, use the -t (tar) command followed by the name of the file(s) to be archived. You may specify multiple filenames using commas. Use the −z (zip) command to compress the archive. For example, if you want to zip up three directories named dir1, dir2, and If an archive doesn't already exists, then one is created instead. If the ar command succeeds, then we should get a static archive file named libfile.a. Let's take a look at what's included in the libfile.a library file −

$ ar -t libfile.a

This command lists all the object files that were archived into the libfile.a. When we want to use the library later on, we can just add the library to the compile command.

$ gcc -o MyProgram *.o -L path/to/libdir -lfile.a

Specifying the −L option tells the compiler where to look for libraries. Make sure you use the correct file name for the command. We replaced the library prefix with −l. The MyProgram executable includes the object code for the libfile.a shared library.

Building .so or Shared Library

You can easily build a shared library using GCC. We first must compile our source code into its corresponding object code −

$ gcc -Wall -c *.c

After compiling the source file into an executable, we will need to run another program to generate a shared library from the executable.

$ gcc -shared -o libfile.so *.o

When using the -shared flag, specify that we're building a shared object file. After successfully compiling, we'll have created a shared object file that we can use to link against from any program.

Conclusion

We learned how most programs run on Linux systems and how they depend on various types of library files. We then examined static and dynamic library files and their purposes. Finally, we saw an example of how we could create static and dynamic library files for our own programs using gcc and its helper tool, ar.

Updated on: 23-Dec-2022

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements