Subject: Saving old shared libraries, part I [was Re: install and update
To: Michael Richardson <mcr@sandelman.ottawa.on.ca>
From: Frederick Bruckman <fb@enteract.com>
List: tech-pkg
Date: 05/31/2001 10:52:57
On Thu, 31 May 2001, Michael Richardson wrote:

>   I would prefer that if one has a dependancy like:
>
>     A --> B --> C --> D
>
>   (D depends on libraries C, B and A, Easy with gnome apps)
>
>   And I want to install:
>     A' --> Z
>
>   that A and A' can coexist. At least, that the files (i.e. .so's) for
> A can coexist with A'. if this puts some new constraint on ELF that wasn't
> there with A.OUT (that silly symlink?), then I'd like to know if we can
> fix that problem instead.

The symlinks are a plus, since they let you control which library is
to be linked, seperately from which libraries are to be run. That
doesn't matter so much if the numbers only increase, but it could be
handy if you wanted to revert A while still retaining packages that
were built against A'.

I can outline a solution for the package system. You must realize,
first, that this only lets the package system get out of the way, so
it can do at least as well as "make install" without a package system.
In fact, you can do something like this already, with "pkg_delete -O
A; cd .../A; make install". The general problem is still intractable,
however, even with ELF.

Consider the following little web of dependencies:

    libA --> libB
          \      \
           \      \
             libC --> D

That is, libB and libC each depend on libA, and in turn satisfy
dependencies for D.

Now what happens when you update libA to libA' in place, and libA'
involves a minor bump? If D only pulls in -lA indirectly, through -lB
and -lC, you'll be able to build it just as before, getting A instead
of A'. You'll be using A' headers, but that may be OK, as long as you
don't call any of the new functions in the interface (remember, it was
only a minor bump, so no functions were removed). If D builds
conditionally on the existence of some new function in the headers for
libA, you're screwed -- in that case, D won't even link.

Now consider what happens if D includes -lA on it's link command line,
or if one of libB or libC are updated in the meantime (but not both).
You'll end up linking against both -lA and lA', which will cause "ld"
to generate a warning. This may work, even if D uses a new function,
but for any old library function, it's not clear _which_ library is
being used. You will also have the problem that the resultant binary
package for D is not portable, as it will require libA and libA' (on
ELF systems), nor will this be reflected in the package dependencies.

It's mostly worse if libA gets a major bump. In the former case, it
just doesn't work at all. In the latter case, again, you may get away
with it if libA' only deletes functions. If the two versions have
functions with the same name but different number of arguments, you've
got a 50-50 chance of corrupting the stack.

That last assumes that it's done right, so that a major bump for libA
induces a major bump in libC and libD. This is not always done. Case
in point, libpng was just bumped post-1.5.1 tag, while imlib and
gnome-libs were not touched. Needless to say, this is going to result
in a lot of squeals of pain, when peoply try to go forward from
1.5/1.5.1, but see my other posts on this. I'm tired of dwelling on it.



Frederick