# Debian packaging manual - chapter 12
Shared libraries

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.

If you do the above your package does not need to call `ldconfig` in its maintainer scripts. It is especially 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!

## 12.1 The `shlibs` File Format

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.

## 12.2 Further Technical information on `shlibs`

### 12.2.1 What are the `shlibs` files?

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

- `/etc/dpkg/shlibs.default`

- `/etc/dpkg/shlibs.override`

- `/var/lib/dpkg/info/*.shlibs`

- `debian/shlibs.local`

These files are used by `dpkg-shlibdeps` when creating a binary package.

### 12.2.2 How does `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

- the package containing the library, and
- the library version number,

it scans the following files in this order.

1. `debian/shlibs.local`
2. `/etc/dpkg/shlibs.override`
3. `/var/lib/dpkg/info/*.shlibs`
4. `/etc/dpkg/shlibs.default`

### 12.2.3 Who maintains the various `shlibs` files?

- `/etc/dpkg/shlibs.default` - the maintainer of dpkg
- `/var/lib/dpkg/info/`package`.shlibs` - the maintainer of each package
- `/etc/dpkg/shlibs.override` - the local system administrator
- `debian/shlibs.local` - the maintainer of the package

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.

### 12.2.4 How to use `dpkg-shlibdeps` and the `shlibs` files?

#### 12.2.4.1 If your package doesn't provide a shared library

Put a call to `dpkg-shlibs` into your `debian/rules` file. If your package contains only binaries (e.g. no scripts) use:

    dpkg-shlibdeps debian/tmp/usr/{bin,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.

#### 12.2.4.2 If your package provides a shared library

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.

### 12.2.5 How to write `debian/shlibs.local`

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.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. <

Debian packaging manual - Copyright ©1996 Ian Jackson.
Contents; abstract; next; back.