Packages containing shared libraries must be constructed with a little care to make sure that the shared library is always available. This is especially important for packages whose shared libraries are vitally important, such as the libc.
Firstly, your package should install the shared libraries under their normal
names. For example, the libgdbm1
package should install
libgdbm.so.1.7.3 as /usr/lib/libgdbm.so.1.7.3. The
files should not be renamed or re-linked by any prerm or postrm scripts;
dpkg
will take care of renaming things safely without affecting
running programs, and attempts to interfere with this are likely to lead to
problems.
Secondly, your package should include the symlink that ldconfig
would create for the shared libraries. For example, the libgdbm1
package should include a symlink from /usr/lib/libgdbm.so.1 to
libgdbm.so.1.7.3. This is needed so that ld.so
can
find the library in between the time dpkg
installs it and
ldconfig
is run in the postinst
script. Furthermore,
older versions of the package management system required the library must be
placed before the symlink pointing to it in the .deb file. This
is so that by the time dpkg
comes to install the symlink
(overwriting the previous symlink pointing at an older version of the library)
the new shared library is already in place. Unfortunately, this was not not
always possible, since it highly depends on the behavior of the file system.
Some file systems (such as reiserfs) will reorder the files so it doesn't
matter in what order you create them. Starting with release 1.7.0
dpkg
will reorder the files itself when building a package.
Thirdly, the development package should contain a symlink for the shared
library without a version number. For example, the libgdbm1-dev
package should include a symlink from /usr/lib/libgdm.so to
libgdm.so.1.7.3. This symlink is needed by ld
when
compiling packages as it will only look for libgdm.so and
libgdm.a when compiling dynamically or statically, respectively.
Any package installing shared libraries in a directory that's listed in
/etc/ld.so.conf or in one of the default library directories of
ld.so
(currently, these are /usr/lib and
/lib) must call ldconfig
in its postinst
script if and only if the first argument is `configure'. However, it is
important not to call ldconfig
in the postrm or preinst scripts in
the case where the package is being upgraded (see Details of unpack phase of
installation or upgrade, Section 6.5), as ldconfig
will see
the temporary names that dpkg
uses for the files while it is
installing them and will make the shared library links point to them, just
before dpkg
continues the installation and removes the links!
This file is for use by dpkg-shlibdeps
and is required when your
package provides shared libraries.
Each line is of the form:
library-name version-or-soname dependencies ...
library-name is the name of the shared library, for example libc5.
version-or-soname is the soname of the library - i.e., the thing
that must exactly match for the library to be recognized by ld.so
.
Usually this is major version number of the library.
dependencies has the same syntax as a dependency field in a binary package control file. It should give details of which package(s) are required to satisfy a binary built against the version of the library contained in the package. See Syntax of relationship fields, Section 7.1.
For example, if the package foo contains libfoo.so.1.2.3, where the soname of the library is libfoo.so.1, and the first version of the package which contained a minor number of at least 2.3 was 1.2.3-1, then the package's shlibs could say:
libfoo 1 foo (>= 1.2.3-1)
The version-specific dependency is to avoid warnings from ld.so
about using older shared libraries with newer binaries.
The debian/shlibs file provides a way of checking for shared library dependencies on packaged binaries. They are intended to be used by package maintainers to make their lives easier.
Other shlibs files that exist on a Debian system are
These files are used by dpkg-shlibdeps
when creating a binary
package.
dpkg-shlibdeps
work?
dpkg-shlibdeps
determines the shared libraries directly [18] used by the compiled binaries (and
libraries, in a version of dpkg-shlibdeps
coming soon) passed
through on its command line.
For each shared library, dpkg-shlibdeps
needs to know
it scans the following files in this order.
The shlibs.default file is managed by dpkg
. The
entries in shlibs.default that are provided by dpkg
are just there to fix things until the shared library packages all have
shlibs files.
dpkg-shlibdeps
and the shlibs files?
Put a call to dpkg-shlibdeps
into your debian/rules
file. If your package contains only binaries (e.g. no scripts) use:
dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/*
If dpkg-shlibdeps
doesn't complain, you're done. If it does
complain you might need to create your own debian/shlibs.local
file.
Create a debian/shlibs file and let debian/rules install it in the control area:
install -m644 debian/shlibs debian/tmp/DEBIAN
If your package contains additional binaries see above.
This file is intended only as a temporary fix if your binaries depend on a library which doesn't provide its own /var/lib/dpkg/info/*.shlibs file yet.
Let's assume you are packaging a binary foo. Your output in building the package might look like this.
$ ldd foo libbar.so.1 => /usr/X11R6/lib/libbar.so.1.0 libc.so.5 => /lib/libc.so.5.2.18 libX11.so.6 => /usr/X11R6/lib/libX11.so.6.0
And when you ran dpkg-shlibdeps
$ dpkg-shlibdeps -o foo dpkg-shlibdeps: warning: unable to find dependency information for shared library libbar (soname 1, path /usr/X11R6/lib/libbar.so.1.0, dependency field Depends) shlibs:Depends=elf-x11r6lib, libc5 (>= 5.2.18)
The foo
binary depends on the libbar
shared library,
but no package seems to provide a *.shlibs file in
var/lib/dpkg/info/. Let's determine the package responsible:
$ dpkg -S /usr/X11R6/lib/libbar.so.1.0 bar1: /usr/X11R6/lib/libbar.so.1.0 $ dpkg -s bar1 | grep Version Version: 1.0-1
This tells us that the bar1
package, version 1.0-1 is the one we
are using. Now we can create our own debian/shlibs.local to
temporarily fix the above problem. Include the following line into your
debian/shlibs.local file.
libbar 1 bar1 (>= 1.0-1)
Now your package build should work. As soon as the maintainer of
libbar1
provides a shlibs file, you can remove your
debian/shlibs.local file.
ijackson@gnu.ai.mit.edu
schwarz@debian.org
bweaver@debian.org
debian-policy@lists.debian.org