Create libraries with GCC

Learn about the steps to create libraries and the concepts the Linux operating system uses for libraries, including sonames, symbolic links, and library file naming conventions.

The soname mechanism

To manage multiple compatible versions of a library, dynamically loaded libraries (shared objects) use the soname mechanism.

  • You must understand dynamic linking and libraries.
  • You must understand the concept of ABI compatibility.
  • You must understand library naming conventions.
  • You must understand symbolic links.
    Problem introduction
    A dynamically loaded library (shared object) exists as an independent executable file. This makes it possible to update the library without updating the applications that depend on it. However, the following problems arise with this concept:
  • Identification of the actual version of the library
  • Need for multiple versions of the same library present
  • Signalling ABI compatibility of each of the multiple versions
    The soname mechanism
    The soname mechanism resolves these problems by using naming conventions to indicate compatibility. A foo library version X.Y is ABI-compatible with other versions with the same value of X in a version number. Minor changes preserving compatibility increase the number Y. Major changes that break compatibility increase the number X.

The actual foo library version X.Y exists as a file libfoo.so.x.y. Inside the library file, a soname is recorded with value libfoo.so.x to signal the compatibility.

During the build, the linker searches for a symbolic link named libfoo.so that points to the library file. A symbolic link with this name must exist, pointing to the actual library file. The linker then reads the soname from the library file and records it into the application executable file. Finally, the linker creates the application that declares dependency on the library by using the soname, not a name or a file name.

When the runtime dynamic linker links an application before running, it reads the soname from application’s executable file. This soname is libfoo.so.x. A symbolic link with this name must exist, pointing to the actual library file. This allows loading the library, regardless of the Y component of a version, because the soname does not change.

Note

The Y component of the version number is not limited to just a single number. Additionally, some libraries encode their version in their name.

Reading soname from a file

To display the soname of a library file somelibrary:

$ objdump -p somelibrary | grep SONAME

Replace somelibrary with the actual file name of the library that you want to examine.

Finding a library name and version in a file name

As an example, consider a library which is present as a file libevent-2.0.so.5.1.9. To find the actual components:

  1. Start by ignoring the standard library file name prefix lib.
  2. Break the remainder into the two parts preceding and following the string .so..
  3. The first part is event-2.0, which is the name of the library.
  4. The second part is 5.1.9. To find the X version component, take everything before first dot: 5.
  5. The rest is the Y version component: 1.9.

Therefore the library’s name is event-2.0, the X version component is 5, and Y is 1.9.

The soname of this library file is everything up to the Y component: libevent-2.0.so.5.

When a newer but still compatible version of the library is released, it uses the same soname, and the Y version component is increased. The new file name is libevent-2.0.so.5.1.10.

Create dynamic libraries with the GCC

To build and install a dynamic library from the source code, you can use the GNU Compiler Collection (GCC). Dynamically linked libraries, also known as shared objects, help you conserve resources by reusing code and increase security by making library updates easier.

Before you begin

Procedure

  1. Change to the directory with library sources.
  2. Compile each source file to an object file with the Position independent code option -fPIC:
    $ gcc ... -c -fPIC some_file.c ...

    The object files have the same file names as the original source code files, but their extension is .o.

  3. Link the shared library from the object files:
    $ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.xsome_file.o ...

    The used major version number is X and minor version number Y.

  4. Copy the libfoo.so.x.y file to an appropriate location, where the system’s dynamic linker can find it. On Red Hat Enterprise Linux, the directory for libraries is /usr/lib64:
    # cp libfoo.so.x.y /usr/lib64

    Note that you need root permissions to manipulate files in this directory.

  5. Create the symlink for the soname:
    # ln -s libfoo.so.x.ylibfoo.so.x
  6. Create the symlink for the linker name:
    # ln -s libfoo.so.xlibfoo.so

Create static libraries with the GCC and ar

To create static libraries, bundle object files into an archive by using the ar utility. Use the resulting .a file for static linking and for distributing self-contained libraries without external dependencies.

Before you begin

About this task

Note

Static linking embeds library code in the archive and in executables that link against it. When you statically link against libraries that Red Hat provides, security updates to those libraries are not applied through routine package updates to shared objects. Use static linking only when you need a self-contained library or binary, or when a library is available for static linking only.

Procedure

  1. Create intermediate object files with GCC:
    $ gcc -c source_file.c ...

    Append more source files if required. The resulting object files share the file name but use the .o file name extension.

  2. Turn the object files into a static library (archive) by using the ar tool from the binutils package:
    $ ar rcs libfoo.a source_file.o ...

    File libfoo.a is created.

  3. Use the nm command to inspect the resulting archive:
    $ nm libfoo.a
  4. Copy the static library file to the appropriate directory.
  5. Link against the library. GCC automatically recognizes from the .a file name extension that the library is an archive for static linking:
    $ gcc ... -lfoo ...