Subject: Shared library dependencies revisited

From: Ian Jackson <[email-masked]>
Date: Mon, 12 Aug 96 14:40 BST

Please read the proposal below and comment on it.  If noone says
anything I'll probably implement and mandate something very like it in
the next week or two, in time for the new source package format (we
only want to change this once).  Now is the time to have your say.

I've been thinking about shared library dependencies some more and
have come to the conclusion that the current scheme is not good
enough.  As the new source format spec stands every package which
depends on a shared library must have hardcoded into the
debian/control which shared libraries are involved - the names and
version numbers of the packages must be entered manually into the
Depends or Recommends fields.

This will mean, amongst other things, that when we move to libc6 we
won't just be able to recompile the packages - we'll have to edit the
control files too.  This is already causing the alpha people problems
because their libcs are different.

I propose the following arrangement (if you don't understand things
you should read dpkg-source(1) and the relevant parts of the new
programmers' manual):

Every package which contains compiled binaries invokes, in its
debian/rules, a program which automatically determines what the
dependencies are.  Eg,
  dpkg-shlibdeps -fPre-Depends main/dpkg dselect/dselect
This produces on stdout something like
  shlib-Pre-Depends=libc5 (>= 5.2.18-2), ncurses3.0 (>= 1.9.9e-1)
(The -fpre-depends option can be -fDepends, -fRecommends or even
-fSuggests to specify a particular level of dependency, and
-f... options can be mixed with binary arguments).

The debian/rules puts the output in debian/substvars.  Then when it
runs dpkg-gencontrol the main source control file can say:
  Source: dpkg
  ...

  Package: dpkg
  Pre-Depends: ${shlib-Pre-Depends}
  ...

The dpkg-shlibdeps program works as follows: it runs ldd on the binary
in question, finding out which libraries are being loaded.  It uses
dpkg --search to find which packages they are in.  It then looks in a
file provided by that package to find out what the dependency name
ought to be (for example, libX11.so.6 is in xlib but the dependency
name should be elf-x11r6lib) and what version is required to make
ld.so not complain.  The file has lines looking like
  <libname>.so.<soname> <dependency>
eg
  libX11.so.6   elf-x11r6lib
  libc.so.5     libc5 (>= 5.2.18-2)

I'm not sure where to put the package-provided file.  Three
possibilities come to mind:
 * /etc/dpkg/shlibs/<package>
 * /usr/lib/dpkg/shlibs/<package>
 * /var/lib/dpkg/info/<package>.shlibs (came from DEBIAN/shlibs)

/etc has the feature that it can be a conffile, though it's not clear
to me whether this is necessary.  The second and third options seem
much of a muchness to me, but I'm inclined towards the /var/lib/dpkg
location as this will effectively hide the real location from anyone
but dpkg (the package maintainer puts the file in DEBIAN/shlibs and
dpkg-shlibdeps is the only thing that needs to find it).

There ought to be a conffile /etc/dpkg/shlibs.default which contains
overriding entries (and can be used to avoid problems when the shared
library in question didn't come from a Debian package, for example
when bootstrapping).

Ian.

---

From: Maarten Boekhold <[email-masked]>
Date: Mon, 12 Aug 1996 19:31:09 +0200 (MET DST)

> -f... options can be mixed with binary arguments).

And what about packages that depend on *one* particular version of a
library? I know of one library which will cause trouble, namely libslang.
This library changes every minor version update so that programs compiled
with earlier versions will not work (I'm not into shared libs, but I think
I'm correct if I say that the ABI changes not only with .so-name changes).

Maarten

_______________________________________________________________________
| Maarten Boekhold, Faculty of Electrical Engineering TU Delft,   NL  |
|   [email-masked] [email-masked]   |
-----------------------------------------------------------------------

---

From: Mark Eichin <[email-masked]>
Date: 12 Aug 1996 13:56:38 -0400

>>   libc.so.5     libc5 (>= 5.2.18-2)

Hmm. How are we going to determine the minor versions?  I run an
"unstable" system and use it for my development -- but my packages are
mostly user applications that really don't care about the particular
rev of libc, just about the soname... so emacs, for example, needs
5.2.18, but really doesn't care if it's -2 or -9...

---

From: Ian Jackson <[email-masked]>
Date: Tue, 13 Aug 96 14:18 BST

Maarten Boekhold writes ("Re: Shared library dependencies revisited"):
...
> with earlier versions will not work [...]

There is no problem with this - it's not even a special case.  I'm
assuming that the whole library version is in the soname.

Of course the library soname has to be encoded into the package name,
so that different versions can coexist.

Can the upstream authors not be persuaded to do better ?

> [...] (I'm not into shared libs, but I think

Yes.

Ian.

---

From: Ian Jackson <[email-masked]>
Date: Tue, 13 Aug 96 14:20 BST

> 5.2.18, but really doesn't care if it's -2 or -9...

The package version is the first one which contained the library with
the correct minor version so that ld.so doesn't complain.  I don't
know how you determine this, but it's specific to the shared library
and you can do it however you like when you build the library package.
dpkg-shlibdeps just looks the details up in the file provided by the
library package.

libc5 is an exception because 5.2.18-2 is the first one that had the
right dependencies &c for ELF conversion.

Ian.