Linker and Libraries Guide

Coordination of Versioned Filenames

A link-edit commonly references shared object dependencies using the link-editors -l option. This option uses 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 as a versioned file name. Instead of maintaining two distinct shared objects that follow two naming conventions, create file system links between the two file names.

For example, the shared object libfoo.so.1 can be made available to the compilation environment by using a symbolic link. The compilation file name is a symbolic link to the runtime file name.


$ 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

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

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


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

The link-editor processes the relocatable object main.o with the interface described by the shared object libfoo.so.1, which is found by following the symbolic link libfoo.so.

Over a series of software releases, new versions of libfoo.so can be distributed with changed interfaces. The compilation environment can be constructed to use the interface that is applicable by changing the symbolic link.


$ 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

In this example, three major versions of the shared object are available. Two versions, 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.

The use of this symbolic link mechanism solely is insufficient to coordinate the compilation shared object with a runtime versioned file name. As the example presently stands, the link-editor records in the dynamic executable prog the file name of the shared object the link-editor processes. In this case, that file name seen by the link-editor is the compilation environment file.


$ dump -Lv prog

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

When the application prog is executed, the runtime linker searches for the dependency libfoo.so. prog binds to the file to which this symbolic link is pointing.

To ensure the correct runtime name is 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. This name is used as the dependency name by any object that links against the shared object. This definition can be provided using the -h option during the creation of the shared object.


$ 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 establish a robust coordination between the shared-object naming conventions of the compilation and runtime environment. The interface processed during the link-edit is accurately recorded in the output file generated. This recording ensures that the intended interface are furnished at runtime.