[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problems with libtool implementation of osf style versioning

From: Rainer Orth
Subject: Problems with libtool implementation of osf style versioning
Date: Mon, 10 Jun 2002 15:08:45 +0200 (MEST)

Trying to install both gcc 2.95 and 3.1 on Tru64 UNIX into a common prefix,
I noticed a serious problem with the current implementation of the osf
versioning style.

[I know that this type of gcc installation is not supported, at least not
for parallel gcc 3.0 and 3.1 installations.  For gcc 2.95, there are no
header name/directory conflicts, and even with
--enable-version-specific-runtime-libs, the libtool problem described below
remains.  I'm copying this message to the gcc mailing list since I'd like
to get the proposed change into gcc 3.1.1 if its accepted by libtool

Consider a library with the following version history (the three args to
-version-info are current, age, and revision):

-version-info 0:0:0
-version-info 0:1:0
-version-info 1:0:1
-version-info 1:1:1
-version-info 2:0:0

For the osf style versioning used on Tru64 UNIX, this is implemented as

osf     Files                           SONAME          IVERSION

0:0:0             0.0.0:0.0
0:1:0             0.0.1:0.0
1:0:1             1.1.0:0.0:1.0
1:1:1             1.1.1:0.0:1.0
2:0:0             2.0.0:2.0

I.e. libtool installs$current.$age.$revision and a symlink.
All versions have the same SONAME; the version information is only
encoded in the IVERSION field (set via -set_version, displayed with odump
-Dv).  The latter contains first the $current.$age.$revision (used only for
informational purposes), and then a list -- oldest to newest -- of the major
versions implemented by this shared object.

For some background information on Tru64 UNIX versioning, see

The problem with this implementation is as follows: unlike the otherwise
similar irix style versioning (described in
the version identifiers in the osf style are opaque strings (i.e. no
sgi$major.$minor structure interpreted by the runtime linker).  The runtime
linker handles version information as follows: it looks up a shared object
required by the binary in question in the usual search path and checks if
the found shared object has the version identifier required by the binary
anywhere in it's IVERSION field.  If so, the dso is used and all is fine.
Otherwise, it tries to locate a matching version of the dso in a subdir
named after the version identifier.

In the example above, a binary linked against version 0:0:0 records the
version identifier 0.0.  If in the meantime version 2:0:0 has been
installed in the same libdir, the runtime linker finds that version 0.0 is
missing from the IVERSION field and tries to locate a correct one in
libdir/0.0/, otherwise the binary fails to run.

This scheme is problematic in that it requires creating those
subdirectories and moving/copying old library versions there before
installing a subsequent version.  Unlike other versioning implementations,
this requires manual intervention and may clutter libdir with many version
subdirs.  Besides, this library search in a subdirectory is only triggered
if a non-matching library with the same SONAME is found in libdir; if it is
missing, the older version in a subdir won't be looked for/found even if

Except for the fact that the version identifiers have a defined structure,
the original IRIX scheme is identical.  SGI suggests to use a SONAME
without version information.  If the runtime linker doesn't find a matching
version in the installed library, it looks for a file named SONAME.$major
(where $major is from the sgi$major.$minor version identifier).  Contrary
to this, the libtool implementation of the irix versioning scheme always
adds .$current to the installed libraries' SONAMEs, thus avoiding this
double lookup.

To avoid both the need for manual intervention by creating subdirectories
of libdir and moving old versions there and the unnecessary double access
to newer and old library version, I suggest that libtool implements the osf
style versioning scheme like it currently does for the irix style.

The example above would look like this instead:

osf     Files                           SONAME          IVERSION

0:0:0        0.0.0:0.0
0:1:0        0.0.1:0.0
1:0:1        1.1.0:1.0:0.0
1:1:1        1.1.1:1.0:0.0
2:0:0        2.0.0:2.0

This is a merge of the linux (used on Solaris 2 as well) and irix
versioning schemes, listed below for reference:

linux   Files                           SONAME


irix    Files                           SONAME          IVERSION

0:0:0        sgi1.0
0:1:0        sgi1.0:sgi1.1
1:0:1        sgi1.0
1:1:1        sgi1.0:sgi1.1
2:0:0        sgi3.0

The changes in the proposed new scheme are as follows:

* Record the oldest compatible version in the SONAME and install a matching
  symlink.  This avoids the need for manually creating subdirs and moving
  old versions there.

* Install the libraries as$major.$age.$revision as in the linux
  scheme.  Since those filenames are not used except as symlink targets,
  this change won't affect any binary, whether built with the old or new
  implementations of the osf versioning scheme.

* Record the same triplet in the IVERSION field.  As above, this is purely
  informational, so nobody is affected by this change.

* Revert the ordering of major versions in the IVERSION field.  This will
  cause binaries linked against a `new' library to pick up the oldest
  version implemented, not the newest one.

  Unlike the irix scheme (which only records revision information for the
  current version in the IVERSION field; this is problematic in itself, but
  not the focus of the current message), the osf style recorded all
  compatible versions implemented by the current dso, so we need to list
  all of them so binaries linked against either old 1.0 or 0.0 versions
  will continue to run.

If there's agreement that this change (primarily the encoding of the major
version in the SONAME) is reasonable, I'll post a patch to implement this.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]