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 C library (currently libc6).
Packages involving shared libraries should be split up into several binary packages. This section mostly deals with how this separation is to be accomplished; rules for files within the shared library packages are in Libraries, Section 10.2 instead.
The run-time shared library needs to be placed in a package called
librarynamesoversion
, where
soversion
is the version number in the soname of the
shared library[40].
Alternatively, if it would be confusing to directly append soversion
to libraryname (e.g. because libraryname itself ends in
a number), you may use libraryname-soversion
and libraryname-soversion-dev
instead.
If you have several shared libraries built from the same source tree you may lump them all together into a single shared library package, provided that you change all of their sonames at once (so that you don't get filename clashes if you try to install different versions of the combined shared libraries package).
The package should install the shared libraries under their normal names. For
example, the libgdbm3
package should install
libgdbm.so.3.0.0
as /usr/lib/libgdbm.so.3.0.0
. 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.
Shared libraries should not be installed executable, since the dynamic linker does not require this and trying to execute a shared library usually results in a core dump.
The run-time library package should include the symbolic link that
ldconfig
would create for the shared libraries. For example, the
libgdbm3
package should include a symbolic link from
/usr/lib/libgdbm.so.3
to libgdbm.so.3.0.0
. This is
needed so that the dynamic linker (for example ld.so
or
ld-linux.so.*
) can find the library between the time that
dpkg
installs it and the time that ldconfig
is run in
the postinst
script.[41]
Any package installing shared libraries in one of the default library
directories of the dynamic linker (which are currently /usr/lib
and /lib
) or a directory that is listed in
/etc/ld.so.conf
[42]
must use ldconfig
to update the shared library system.
The package must call ldconfig
in the postinst
script
if the first argument is configure; the postinst
script may optionally invoke ldconfig
at other times. The package
should call ldconfig
in the postrm
script if the
first argument is remove. The maintainer scripts must not invoke
ldconfig
under any circumstances other than those described in
this paragraph.[43]
If your package has some run-time support programs which use the shared library you must not put them in the shared library package. If you do that then you won't be able to install several versions of the shared library without getting filename clashes.
Instead, either create another package for the runtime binaries (this package
might typically be named libraryname-runtime
; note the
absence of the soversion in the package name), or if the development
package is small, include them in there.
The static library (libraryname.a
) is usually provided
in addition to the shared version. It is placed into the development package
(see below).
In some cases, it is acceptable for a library to be available in static form only; these cases include:
The development files associated to a shared library need to be placed in a
package called librarynamesoversion-dev
, or
if you prefer only to support one development version at a time,
libraryname-dev
.
In case several development versions of a library exist, you may need to use
dpkg
's Conflicts mechanism (see Conflicting binary packages -
Conflicts, Section 7.3) to ensure that the user only installs
one development version at a time (as different development versions are likely
to have the same header files in them, which would cause a filename clash if
both were installed).
The development package should contain a symlink for the associated shared
library without a version number. For example, the libgdbm-dev
package should include a symlink from /usr/lib/libgdbm.so
to
libgdbm.so.3.0.0
. This symlink is needed by the linker
(ld
) when compiling packages, as it will only look for
libgdbm.so
when compiling dynamically.
Typically the development version should have an exact version dependency on the runtime library, to make sure that compilation and linking happens correctly. The ${Source-Version} substitution variable can be useful for this purpose.
If a package contains a binary or library which links to a shared library, we
must ensure that when the package is installed on the system, all of the
libraries needed are also installed. This requirement led to the creation of
the shlibs system, which is very simple in its design: any package
which provides a shared library also provides information on the
package dependencies required to ensure the presence of this library, and any
package which uses a shared library uses this information to determine
the dependencies it requires. The files which contain the mapping from shared
libraries to the necessary dependency information are called
shlibs
files.
Thus, when a package is built which contains any shared libraries, it must
provide a shlibs
file for other packages to use, and when a
package is built which contains any shared libraries or compiled binaries, it
must run dpkg-shlibdeps
on these to determine the libraries used and hence the dependencies needed by
this package.[44]
In the following sections, we will first describe where the various
shlibs files are to be found, then how to use
dpkg-shlibdeps
, and finally the shlibs file format
and how to create them if your package contains a shared library.
There are several places where shlibs files are found. The
following list gives them in the order in which they are read by dpkg-shlibdeps
.
(The first one which gives the required information is used.)
debian/shlibs.local
This lists overrides for this package. Its use is described below (see Writing the debian/shlibs.local
file,
Section 8.6.5).
/etc/dpkg/shlibs.override
This lists global overrides. This list is normally empty. It is maintained by the local system administrator.
DEBIAN/shlibs
files in the "build directory"
When packages are being built, any debian/shlibs
files are copied
into the control file area of the temporary build directory and given the name
shlibs
. These files give details of any shared libraries included
in the package.[45]
/var/lib/dpkg/info/*.shlibs
These are the shlibs
files corresponding to all of the packages
installed on the system, and are maintained by the relevant package
maintainers.
/etc/dpkg/shlibs.default
This file lists any shared libraries whose packages have failed to provide
correct shlibs
files. It was used when the shlibs
setup was first introduced, but it is now normally empty. It is maintained by
the dpkg maintainer.
dpkg-shlibdeps
and the shlibs
files
Put a call to dpkg-shlibdeps
into your debian/rules
file. If your package contains only
compiled binaries and libraries (but no scripts), you can use a command such
as:
dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/* \ debian/tmp/usr/lib/*
Otherwise, you will need to explicitly list the compiled binaries and libraries.[46]
This command puts the dependency information into the
debian/substvars
file, which is then used by
dpkg-gencontrol
. You will need to place a
${shlib:Depends} variable in the Depends field in the
control file for this to work.
If dpkg-shlibdeps
doesn't complain, you're done. If it does
complain you might need to create your own debian/shlibs.local
file, as explained below (see Writing the
debian/shlibs.local
file, Section 8.6.5).
If you have multiple binary packages, you will need to call
dpkg-shlibdeps
on each one which contains compiled libraries or
binaries. In such a case, you will need to use the -T option to
the dpkg utilities to specify a different substvars
file.
For more details on dpkg-shlibdeps, please see dpkg-shlibdeps
-
calculates shared library dependencies, Section C.1.4 and
dpkg-shlibdeps(1)
.
shlibs
File Format
Each shlibs
file has the same format. Lines beginning with
# are considered to be comments and are ignored. Each line is of
the form:
library-name soname-version-number dependencies ...
We will explain this by reference to the example of the zlib1g
package, which (at the time of writing) installs the shared library
/usr/lib/libz.so.1.1.3
.
library-name is the name of the shared library, in this case libz. (This must match the name part of the soname, see below.)
soname-version-number is the version part of the soname of the library. The soname is the thing that must exactly match for the library to be recognized by the dynamic linker, and is usually of the form name.so.major-version, in our example, libz.so.1.[47] The version part is the part which comes after .so., so in our case, it is 1.
dependencies has the same syntax as a dependency field in a binary package control file. It should give details of which packages 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 details.
In our example, if the first version of the zlib1g package which contained a minor number of at least 1.3 was 1:1.1.3-1, then the shlibs entry for this library could say:
libz 1 zlib1g (>= 1:1.1.3)
The version-specific dependency is to avoid warnings from the dynamic linker about using older shared libraries with newer binaries.
shlibs
file
If your package provides a shared library, you should create a
shlibs
file following the format described above. It is usual to
call this file debian/shlibs
(but if you have multiple binary
packages, you might want to call it
debian/shlibs.package
instead). Then let
debian/rules
install it in the control area:
install -m644 debian/shlibs debian/tmp/DEBIAN
or, in the case of a multi-binary package:
install -m644 debian/shlibs.package debian/package/DEBIAN/shlibs
An alternative way of doing this is to create the shlibs
file in
the control area directly from debian/rules
without using a
debian/shlibs
file at all,[48] since the debian/shlibs
file itself is ignored
by dpkg-shlibdeps
.
As dpkg-shlibdeps
reads the DEBIAN/shlibs
files in
all of the binary packages being built from this source package, all of the
DEBIAN/shlibs
files should be installed before
dpkg-shlibdeps
is called on any of the binary packages.
debian/shlibs.local
file
This file is intended only as a temporary fix if your binaries or
libraries depend on a library whose package does not yet provide a correct
shlibs
file.
We will assume that you are trying to package a binary foo. When
you try running dpkg-shlibdeps
you get the following error message
(-O displays the dependency information on stdout
instead of writing it to debian/substvars, and the lines have been
wrapped for ease of reading):
$ dpkg-shlibdeps -O debian/tmp/usr/bin/foo dpkg-shlibdeps: warning: unable to find dependency information for shared library libbar (soname 1, path /usr/lib/libbar.so.1, dependency field Depends) shlibs:Depends=libc6 (>= 2.2.2-2)
You can then run ldd
on the binary to find the full location of
the library concerned:
$ ldd foo libbar.so.1 => /usr/lib/libbar.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40032000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
So the foo
binary depends on the libbar
shared
library, but no package seems to provide a *.shlibs
file handling
libbar.so.1
in /var/lib/dpkg/info/
. Let's determine
the package responsible:
$ dpkg -S /usr/lib/libbar.so.1 bar1: /usr/lib/libbar.so.1 $ 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 file a bug against the bar1 package and
create our own debian/shlibs.local
to locally fix the problem.
Including the following line into your debian/shlibs.local
file:
libbar 1 bar1 (>= 1.0-1)
should allow the package build to work.
As soon as the maintainer of bar1 provides a correct
shlibs
file, you should remove this line from your
debian/shlibs.local
file. (You should probably also then have a
versioned Build-Depends on bar1 to help ensure that
others do not have the same problem building your package.)
Debian Policy Manual
version 3.6.1.1, 2004-06-25