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.
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
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.
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/DEBIANIf 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/*.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.0And 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-1This 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.