The shlibs File Format
-
+
+ However, postrm and preinst scripts
+ must not call ldconfig in the case where
+ the package is being upgraded (see [ for
+ details), 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 renames the temporary files!
+ ]
-
- This file is for use by dpkg-shlibdeps and is
- required when your package provides shared libraries.
-
+
+ Handling shared library dependencies - the
+ shlibs system
+
+
+ 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.
+
+
+ In the past, the shared libraries linked to were
+ determined by calling ldd, but now
+ objdump to do this. The only change this
+ makes to package building is that
+ dpkg-shlibdeps must also be run on shared
+ libraries, whereas in the past this was unnecessary.
+ The rest of this footnote explains the advantage that
+ this method gives.
+
-
- Each line is of the form:
-
- library-name version-or-soname dependencies ...
-
-
+
+ We say that a binary foo directly uses
+ a library libbar if it is explicitly linked
+ with that library (that is, it uses the flag
+ -lbar during the linking stage). Other
+ libraries that are needed by libbar are linked
+ indirectly to foo, and the dynamic
+ linker will load them automatically when it loads
+ libbar. A package should needs to depend on
+ the libraries it directly uses, and the dependencies for
+ those libraries should automatically pull in the other
+ libraries.
+
-
- library-name is the name of the shared library,
- for example libc5.
-
+
+ Unfortunately, the ldd program shows both
+ the directly and indirectly used libraries, meaning that
+ the dependencies determined included both direct and
+ indirect dependencies. The use of objdump
+ avoids this problem by determining only the directly
+ used libraries.
+
-
- 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 the major
- version number of the library.
+
+ A good example of where this helps is the following. We
+ could update libimlib with a new version that
+ supports a new graphics format called dgf (but retaining
+ the same major version number). If we used the old
+ ldd method, every package that uses
+ libimlib would need to be recompiled so it
+ would also depend on libdgf or it wouldn't run
+ due to missing symbols. However with the new system,
+ packages using libimlib can rely on
+ libimlib itself having the dependency on
+ libdgf and so they would not need rebuilding.
+
+
- 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 [.
+ 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.
]
+
+
+ The shlibs files present on the system
+
- 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)
-
+ 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.)
- The version-specific dependency is to avoid warnings from
- ld.so about using older shared libraries with
- newer binaries.
-
-
- Further Technical information on
- shlibs
-
- 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.
-
-
- How does dpkg-shlibdeps
- work?
-
-
- dpkg-shlibdeps
- determines the shared libraries directly
-
+
+ debian/shlibs.local
+ -
- It used to do this by calling ldd, but it
- now calls objdump to do this. This
- requires a couple of changes in the way that packages
- are built.
+ This lists overrides for this package. Its use is
+ described below (see [).
]
+
+
+ /etc/dpkg/shlibs.override
+ -
- A binary foo directly uses a library
- libbar if it is linked with that
- library. Other libraries that are needed by
- libbar are linked indirectly to foo,
- and the dynamic linker will load them automatically
- when it loads libbar. Runningldd
- lists all of the libraries used, both directly and
- indirectly; but objdump only lists the
- directly linked libraries. A package only needs to
- depend on the libraries it is directly linked to,
- since the dependencies for those libraries should
- automatically pull in the other libraries.
+ This lists global overrides. This list is normally
+ empty. It is maintained by the local system
+ administrator.
+
+
+ DEBIAN/shlibs files in the `build directory'
+ -
- This change does mean a change in the way packages are
- build though: currently dpkg-shlibdeps is
- only run on binaries. But since we will now rely on the
- libraries depending on the libraries they themselves
- need, the packages containing those libraries will
- need to run dpkg-shlibdeps on the
- libraries.
+ 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.
+
+
+ An example may help here. Let us say that the
+ source package foo generates two binary
+ packages, libfoo2 and
+ foo-runtime. When building the binary
+ packages, the two packages are created in the
+ directories debian/libfoo2 and
+ debian/foo-runtime respectively.
+ (debian/tmp could be used instead of one
+ of these.) Since libfoo2 provides the
+ libfoo shared library, it will require a
+ shlibs file, which will be installed in
+ debian/libfoo2/DEBIAN/shlibs, eventually
+ to become
+ /var/lib/dpkg/info/libfoo2.shlibs. Then
+ when dpkg-shlibdeps is run on the
+ executable
+ debian/foo-runtime/usr/bin/foo-prog, it
+ will examine the
+ debian/libfoo2/DEBIAN/shlibs file to
+ determine whether foo-prog's library
+ dependencies are satisfied by any of the libraries
+ provided by libfoo2. For this reason,
+ dpkg-shlibdeps must only be run once
+ all of the individual binary packages'
+ shlibs files have been installed into the
+ build directory.
+
+
+
+
+ /var/lib/dpkg/info/*.shlibs
+ -
- A good example where this would help us is the current
- mess with multiple version of the mesa
- library. With the ldd-based system, every
- package that uses mesa needs to add a
- dependency on svgalib|svgalib-dummy in order
- to handle the glide mesa variant. With an
- objdump-based system this isn't necessary
- anymore and would have saved everyone a lot of work.
+ 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
+ -
- Another example: we could update libimlib
- with a new version that supports a new graphics format
- called dgf. If we use the old ldd method,
- every package that uses libimlib would need
- to be recompiled so it would also depend on
- libdgf or it wouldn't run due to missing
- symbols. However with the new system, packages using
- libimlib can rely on libimlib itself
- having the dependency on libdgf and wouldn't
- need to be updated.
+ 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.
-
- used by the compiled binaries and libraries passed through
- on its command line.
-
+
+
+
+
-
- For each shared library linked to,
- dpkg-shlibdeps needs to know
-
- the package containing the library, and
- the library version number,
-
- and it scans the following files in this order:
-
- debian/shlibs.local
- /etc/dpkg/shlibs.override
- /var/lib/dpkg/info/*.shlibs
- /etc/dpkg/shlibs.default
-
-
-
+
+ How to use dpkg-shlibdeps and the
+ shlibs files
- Who maintains the various
- 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.
+
+
+ If you are using debhelper, the
+ dh_shlibdeps program will do this work for
+ you. It will also correctly handle multi-binary
+ packages.
+
+
+
-
-
- -
-
/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.
-
-
+
+ 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.
+
- How to use dpkg-shlibdeps and
- the shlibs files
-
+
+ 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
+ [).
+ ]
- If your package doesn't provide a shared
- library
-
+
+ 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 this and other options, see .
+
+
+
+ The shlibs File Format
+
+
+ Each shlibs file has the same format. Lines
+ beginning with # are considered to be commments 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.
+
- Put a call to dpkg-shlibdeps into your
- debian/rules file. If your package contains
- only binaries (e.g. no scripts) use:
+ This can be determined using the command
- dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/*
+ objdump -p /usr/lib/libz.so.1.1.3 | grep SONAME
- If dpkg-shlibdeps doesn't complain, you're
- done. If it does complain you might need to create your
- own debian/shlibs.local file.
-
+
+
+ The version part is the part which comes after
+ .so., so in our case, it is 1.
+
- If your package provides a shared library
-
+
+ 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 [ 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.
+
+
+
+
+ Providing a 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,
+
- 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 is what dh_makeshlibs in the
+ debhelper suite does.
-
-
+
+ since the debian/shlibs file itself is ignored by
+ dpkg-shlibdeps.
+
- How to write
- debian/shlibs.local
-
+
+ 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.
+
+
-
- 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.
-
+
+ Writing the debian/shlibs.local file
-
- 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 (0x4001e000)
- libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x4002c000)
- libc.so.6 => /lib/libc.so.6 (0x40114000)
- /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
-
- 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=libc6 (>= 2.2.1), xlibs (>= 4.0.1-11)
-
- 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:
-
+
+ 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.
+
-
-
- $ 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.
-
-
+
+ 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.)
+