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

Re: Symbol-versioning a C++ library



On Fri, May 25, 2007 at 09:57:41PM +0200, Florian Weimer wrote:
> > This is slightly off-topic, for which I apologise.  It's just that I
> > learned about symbol versioning during my NM process, and nobody outside
> > Debian seems to understand what it is. :-(

> *sigh* It's a bit sad that this is still being used in the NM process.

No, it's only sad that so many people maintain libraries without
understanding the consequences of ABI changes.

> > I have a library, which I want to package for Debian.  I felt it would
> > be a good idea to use symbol versioning, since most of my programs (and
> > in some cases other libraries) use it.  The library is written in C++,
> > which seems to be a slight problem.  AFAIU the linker should be able to
> > handle it, but I don't see how.  Let's start with the problem in more
> > detail:

> Before you do this, you should check if symbol versioning buys you
> anything in your case.  If an application uses libA and libB which
> both depend on libC, but in two different versions libC1 and libC2,
> and you want to pass a libC-implemented object from libA to libB or
> vice versa, this still does not work.  If libA and libB completely
> hide their dependency on libC, you won't run into such problems.

In my experience, exposing objects in APIs like this remains an exception
rather than a rule.  Regardless, using symbol versioning still limits the
problem to cases where objects are being passed around between multiple
versions of a library *and* the definition of that particular object has
changed.  Without symbol versioning, loading multiple versions of a library
frequently leads to segfaults in library *internals*, regardless of whether
the library has a clean API.

> And there's also problem which is rather C++-specific: When an object
> is created, the size of the object is typically compiled into the
> creator, unversioned.  This means that unless the API is very
> carefully designed, you end up with non-versioned dependencies anyway.

True.  But again, this only shows that symbol versioning is not a panacea --
not that it isn't worth doing.

> The poster child for symbol versioning, GNU libc, uses one source
> version to provide multiple, versioned entry points.  This offers
> complete control over the interplay of versions, and works best for C
> code.  Symbol versioning is no magic bullet that lets you escape DLL
> hell.  In general, what saves us is the ability to recompile large
> parts of our software archive against new library versions, not symbol
> versioning.

In addition to the special case of glibc, symbol versioning (of one sort or
another) has been used for the following libraries to good effect where it
was not practical to just recompile everything against new library versions;
in many of these cases, the impetus for symbol versioning originated with
Debian:

  BDB
  cyrus-sasl
  libkrb5 (MIT and Heimdal)
  libpng
  gnutls
  openssl
  wxwidgets

For *any* library with other libraries as reverse-dependencies, where the
maintainer has considered shipping two upstream versions of the lib in
parallel, unless it's *known* that the API is not safe under symbol
versioning, using symbol versioning should be the default policy.  Even if
only packages linking against the new version of the lib pick up the symbol
versioning, it can still make a *huge* difference in the quality of the
user's experience.

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
vorlon@debian.org                                   http://www.debian.org/



Reply to: