Linker and Libraries Guide

Coordination of Versioned Filenames

In the section "Naming Conventions" it was stated that during a link-edit, the most common method to input shared objects was to use the -l option. This option will use the link-editor's library search mechanism to locate shared objects that are prefixed with lib and suffixed with .so.

However, at runtime, any shared object dependencies should exist in their versioned name form. Instead of maintaining two distinct shared objects that follow these naming conventions, the most common mechanism of coordinating these objects involves creating file system links between the two filenames.

To make the runtime shared object libfoo.so.1 available to the compilation environment, it is necessary to provide a symbolic link from the compilation filename to the runtime filename. For example:


$ cc -o libfoo.so.1 -G -K pic foo.c
$ ln -s libfoo.so.1 libfoo.so
$ ls -l libfoo*
lrwxrwxrwx  1 usr grp          11 1991 libfoo.so -> libfoo.so.1
-rwxrwxr-x  1 usr grp        3136 1991 libfoo.so.1

Note -

Either a symbolic or hard link can be used. However, as a documentation and diagnostic aid, symbolic links are more useful.


Here, the shared object libfoo.so.1 has been generated for the runtime environment. Generating a symbolic link libfoo.so, has also enabled this file's use in a compilation environment. For example:


$ cc -o prog main.o -L. -lfoo

Here, the link-editor will process the relocatable object main.o with the interface described by the shared object libfoo.so.1, which it will find by following the symbolic link libfoo.so.

If over a series of software releases, new versions of this shared object are distributed with changed interfaces, the compilation environment can be constructed to use the interface that is applicable by changing the symbolic link. For example:


$ ls -l libfoo*
lrwxrwxrwx  1 usr grp          11 1993 libfoo.so -> libfoo.so.3
-rwxrwxr-x  1 usr grp        3136 1991 libfoo.so.1
-rwxrwxr-x  1 usr grp        3237 1992 libfoo.so.2
-rwxrwxr-x  1 usr grp        3554 1993 libfoo.so.3

Here, three major versions of the shared object are available. Two of these shared objects, libfoo.so.1 and libfoo.so.2, provide the dependencies for existing applications. libfoo.so.3 offers the latest major release for creating and running new applications.

Using this symbolic link mechanism itself is insufficient to coordinate the correct binding of a shared object from its use in the compilation environment to its requirement in the runtime environment. As the example presently stands, the link-editor will record in the dynamic executable prog the filename of the shared object it has processed, which in this case will be the compilation environment filename:


$ dump -Lv prog

prog:
 **** DYNAMIC SECTION INFORMATION ****
.dynamic:
[INDEX] Tag      Value
[1]     NEEDED   libfoo.so
.........

This means that when the application prog is executed, the runtime linker will search for the dependency libfoo.so; consequently, this will bind to whichever file this symbolic link is pointing.

To provide the correct runtime name to be recorded as a dependency, the shared object libfoo.so.1 should be built with an soname definition. This definition identifies the shared object's runtime name, and is used as the dependency name by any object that links against this shared object. This definition can be provided using the -h option during the link-edit of the shared object itself. For example:


$ cc -o libfoo.so.1 -G -K pic -h libfoo.so.1 foo.c
$ ln -s libfoo.so.1 libfoo.so
$ cc -o prog main.o -L. -lfoo
$ dump -Lv prog

prog:
 **** DYNAMIC SECTION INFORMATION ****
.dynamic:
[INDEX] Tag      Value
[1]     NEEDED   libfoo.so.1
.........

This symbolic link and the soname mechanism has established a robust coordination between the shared object naming conventions of the compilation and runtime environments, one in which the interface processed during the link-edit is accurately recorded in the output file generated. This recording ensures that the intended interface will be furnished at runtime.