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 relinked 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. Futhermore,
and this is very important, 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. Currently the way to ensure the ordering is done properly is
to install the library in the appropriate debian/tmp/.../lib
directory before creating the symlink, by putting the commands in the
debian/rules in the appropriate order. Whether this has been done
correctly can be checked by performing an ls -f.
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.3), 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 - ie, the thing that
must exactly match for the library to be recognised 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 8.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
calls ldd
to determine the shared
libraries used by the compiled binaries passed through 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
temporarly 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
bweaver@debian.org
schwarz@debian.org
srivasta@debian.org
debian-policy@lists.debian.org