Naming Conventions

Neither the link-editor nor the runtime linker interprets any file by virtue of
its file name. All files are inspected to determine their ELF type
(see ELF Header). This information enables the link-editor to deduce the processing requirements
of the file. However, shared objects usually follow one of two naming
conventions, depending on whether they are being used as part of the compilation
environment or the runtime environment.

When used as part of the compilation environment, shared objects are read
and processed by the link-editor. Although these shared objects can be specified by
explicit file names as part of the command passed to the link-editor,
the -l option is usually used to take advantage of the link-editor's library
search facilities. See Shared Object Processing.

A shared object that is applicable to this link-editor processing, should be
designated with the prefix lib and the suffix .so. For example, /lib/libc.so
is the shared object representation of the standard C library made available
to the compilation environment. By convention, 64–bit shared objects are placed in
a subdirectory of the lib directory called 64. For example, the 64–bit counterpart
of /lib/libc.so.1, is /lib/64/libc.so.1.

When used as part of the runtime environment, shared objects are read
and processed by the runtime linker. To allow for change in the
exported interface of the shared object over a series of software releases, provide
the shared object as a versioned file name.

A versioned file name commonly takes the form of a .so suffix
followed by a version number. For example, /lib/libc.so.1 is the shared object
representation of version one of the standard C library made available to the
runtime environment.

If a shared object is never intended for use within a compilation environment,
its name might drop the conventional lib prefix. Examples of shared objects
that fall into this category are those used solely with dlopen(3C). A
suffix of .so is still recommended to indicate the actual file type. In
addition, a version number is strongly recommended to provide for the correct
binding of the shared object across a series of software releases. Chapter 5, Application Binary Interfaces and Versioning
describes versioning in more detail.

Note - The shared object name used in a dlopen(3C) is usually represented as a
simple file name, that has no `/' in the name. The runtime
linker can then use a set of rules to locate the actual
file. See Loading Additional Objects for more details.

Recording a Shared Object Name

The recording of a dependency in a dynamic executable or shared object will,
by default, be the file name of the associated shared object as
it is referenced by the link-editor. For example, the following dynamic executables,
that are built against the same shared object libfoo.so, result in different interpretations
of the same dependency.

As these examples show, this mechanism of recording dependencies can result in
inconsistencies due to different compilation techniques. Also, the location of a shared
object as referenced during the link-edit might differ from the eventual location of
the shared object on an installed system. To provide a more consistent
means of specifying dependencies, shared objects can record within themselves the file name
by which they should be referenced at runtime.

During the link-edit of a shared object, its runtime name can be
recorded within the shared object itself by using the -h option. In the
following example, the shared object's runtime name libfoo.so.1, is recorded within the
file itself. This identification is known as an soname.

$ cc -o ../tmp/libfoo.so -G -K pic -h libfoo.so.1 foo.c

The following example shows how the soname recording can be displayed using
elfdump(1) and referring to the entry that has the SONAME tag.

When the link-editor processes a shared object that contains an soname, this
is the name that is recorded as a dependency within the output
file being generated.

If this new version of libfoo.so is used during the creation of
the dynamic executable prog from the previous example, all three methods of
creating the executable result in the same dependency recording.

In the previous examples, the -h option is used to specify a
simple file name, that has no `/' in the name. This convention
enables the runtime linker to use a set of rules to locate the
actual file. See Locating Shared Object Dependencies for more details.

Inclusion of Shared Objects in Archives

The mechanism of recording an soname within a shared object is essential
if the shared object is ever processed from an archive library.

An archive can be built from one or more shared objects and
then used to generate a dynamic executable or shared object. Shared objects
can be extracted from the archive to satisfy the requirements of the link-edit.
Unlike the processing of relocatable objects, which are concatenated to the output
file being created, any shared objects extracted from the archive are recorded
as dependencies. See Archive Processing for more details on the criteria for archive extraction.

The name of an archive member is constructed by the link-editor and
is a concatenation of the archive name and the object within the
archive. For example.

Because a file with this concatenated name is unlikely to exist at
runtime, providing an soname within the shared object is the only means
of generating a meaningful runtime file name for the dependency.

Note - The runtime linker does not extract objects from archives. Therefore, in this
example, the required shared object dependencies must be extracted from the archive
and made available to the runtime environment.

Recorded Name Conflicts

When shared objects are used to create a dynamic executable or another
shared object, the link-editor performs several consistency checks. These checks ensure that
any dependency names recorded in the output file are unique.

Conflicts in dependency names can occur if two shared objects used as input
files to a link-edit both contain the same soname. For example.