</p>
<p>
- You should not use <prgn>dpkg-divert</prgn> on a file
- belonging to another package without consulting the
- maintainer of that package first.
+ You should not use <prgn>dpkg-divert</prgn> on a file belonging
+ to another package without consulting the maintainer of that
+ package first. When adding or removing diversions, package
+ maintainer scripts must provide the <tt>--package</tt> flag
+ to <prgn>dpkg-divert</prgn> and must not use <tt>--local</tt>.
</p>
<p>
</p>
<p>
- Thus, when a package is built which contains any shared
- libraries, it must provide a <file>shlibs</file> file for other
- packages to use, and when a package is built which contains
- any shared libraries or compiled binaries, it must run
+ When a package is built which contains any shared libraries, it
+ must provide a <file>shlibs</file> file for other packages to
+ use. When a package is built which contains any shared
+ libraries or compiled binaries, it must run
<qref id="pkg-dpkg-shlibdeps"><prgn>dpkg-shlibdeps</prgn></qref>
on these to determine the libraries used and hence the
dependencies needed by this package.<footnote>
<p>
- In the past, the shared libraries linked to were
- determined by calling <prgn>ldd</prgn>, but now
- <prgn>objdump</prgn> is used to do this. The only
- change this makes to package building is that
- <prgn>dpkg-shlibdeps</prgn> 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.
+ <prgn>dpkg-shlibdeps</prgn> will use a program
+ like <prgn>objdump</prgn> or <prgn>readelf</prgn> to find
+ the libraries directly needed by the binaries or shared
+ libraries in the package.
</p>
<p>
We say that a binary <tt>foo</tt> <em>directly</em> uses
a library <tt>libbar</tt> if it is explicitly linked
- with that library (that is, it uses the flag
- <tt>-lbar</tt> during the linking stage). Other
+ with that library (that is, the library is listed in the ELF
+ <tt>NEEDED</tt> attribute, caused by adding <tt>-lbar</tt>
+ to the link line when the binary is created). Other
libraries that are needed by <tt>libbar</tt> are linked
<em>indirectly</em> to <tt>foo</tt>, and the dynamic
linker will load them automatically when it loads
- <tt>libbar</tt>. A package should depend on
- the libraries it directly uses, and the dependencies for
- those libraries should automatically pull in the other
- libraries.
- </p>
-
- <p>
- Unfortunately, the <prgn>ldd</prgn> program shows both
- the directly and indirectly used libraries, meaning that
- the dependencies determined included both direct and
- indirect dependencies. The use of <prgn>objdump</prgn>
- avoids this problem by determining only the directly
- used libraries.
+ <tt>libbar</tt>. A package should depend on the libraries
+ it directly uses, but not the libraries it indirectly uses.
+ The dependencies for those libraries will automatically pull
+ in the other libraries.
</p>
<p>
A good example of where this helps is the following. We
could update <tt>libimlib</tt> with a new version that
- supports a new graphics format called dgf (but retaining
- the same major version number). If we used the old
- <prgn>ldd</prgn> method, every package that uses
- <tt>libimlib</tt> would need to be recompiled so it
- would also depend on <tt>libdgf</tt> or it wouldn't run
- due to missing symbols. However with the new system,
- packages using <tt>libimlib</tt> can rely on
- <tt>libimlib</tt> itself having the dependency on
- <tt>libdgf</tt> and so they would not need rebuilding.
+ supports a new graphics format called dgf (but retaining the
+ same major version number) and depends on <tt>libdgf</tt>.
+ If we used <prgn>ldd</prgn> to add dependencies for every
+ library directly or indirectly linked with a binary, every
+ package that uses <tt>libimlib</tt> would need to be
+ recompiled so it would also depend on <tt>libdgf</tt> or it
+ wouldn't run due to missing symbols. Since dependencies are
+ only added based on ELF <tt>NEEDED</tt> attribute, packages
+ using <tt>libimlib</tt> can rely on <tt>libimlib</tt> itself
+ having the dependency on <tt>libdgf</tt> and so they would
+ not need rebuilding.
</p>
</footnote>
</p>
<p><file>debian/shlibs.local</file></p>
<p>
- This lists overrides for this package. Its use is
- described below (see <ref id="shlibslocal">).
+ This lists overrides for this package. This file should
+ normally not be used, but may be needed temporarily in
+ unusual situations to work around bugs in other packages,
+ or in unusual cases where the normally declared dependency
+ information in the installed <file>shlibs</file> file for
+ a library cannot be used. The contents of this file
+ override information obtained from any other source.
</p>
</item>
<p><file>DEBIAN/shlibs</file> files in the "build directory"</p>
<p>
- When packages are being built, any
- <file>debian/shlibs</file> files are copied into the
+ When packages are being built,
+ any <file>debian/shlibs</file> files are copied into the
control file area of the temporary build directory and
given the name <file>shlibs</file>. These files give
- details of any shared libraries included in the
+ details of any shared libraries included in the same
package.<footnote>
- An example may help here. Let us say that the
- source package <tt>foo</tt> generates two binary
- packages, <tt>libfoo2</tt> and
- <tt>foo-runtime</tt>. When building the binary
- packages, the two packages are created in the
- directories <file>debian/libfoo2</file> and
- <file>debian/foo-runtime</file> respectively.
- (<file>debian/tmp</file> could be used instead of one
- of these.) Since <tt>libfoo2</tt> provides the
- <tt>libfoo</tt> shared library, it will require a
- <tt>shlibs</tt> file, which will be installed in
- <file>debian/libfoo2/DEBIAN/shlibs</file>, eventually
- to become
- <file>/var/lib/dpkg/info/libfoo2.shlibs</file>. Then
- when <prgn>dpkg-shlibdeps</prgn> is run on the
- executable
- <file>debian/foo-runtime/usr/bin/foo-prog</file>, it
- will examine the
- <file>debian/libfoo2/DEBIAN/shlibs</file> file to
- determine whether <tt>foo-prog</tt>'s library
- dependencies are satisfied by any of the libraries
- provided by <tt>libfoo2</tt>. For this reason,
- <prgn>dpkg-shlibdeps</prgn> must only be run once
- all of the individual binary packages'
- <tt>shlibs</tt> files have been installed into the
- build directory.
+ An example may help here. Let us say that the source
+ package <tt>foo</tt> generates two binary
+ packages, <tt>libfoo2</tt> and <tt>foo-runtime</tt>.
+ When building the binary packages, the two packages are
+ created in the directories <file>debian/libfoo2</file>
+ and <file>debian/foo-runtime</file> respectively.
+ (<file>debian/tmp</file> could be used instead of one of
+ these.) Since <tt>libfoo2</tt> provides the
+ <tt>libfoo</tt> shared library, it will require a
+ <tt>shlibs</tt> file, which will be installed in
+ <file>debian/libfoo2/DEBIAN/shlibs</file>, eventually to
+ become <file>/var/lib/dpkg/info/libfoo2.shlibs</file>.
+ When <prgn>dpkg-shlibdeps</prgn> is run on the
+ executable <file>debian/foo-runtime/usr/bin/foo-prog</file>,
+ it will examine
+ the <file>debian/libfoo2/DEBIAN/shlibs</file> file to
+ determine whether <tt>foo-prog</tt>'s library
+ dependencies are satisfied by any of the libraries
+ provided by <tt>libfoo2</tt>. For this reason,
+ <prgn>dpkg-shlibdeps</prgn> must only be run once all of
+ the individual binary packages' <tt>shlibs</tt> files
+ have been installed into the build directory.
</footnote>
</p>
</item>
</example>
Otherwise, you will need to explicitly list the compiled
binaries and libraries.<footnote>
- If you are using <tt>debhelper</tt>, the
- <prgn>dh_shlibdeps</prgn> program will do this work for
- you. It will also correctly handle multi-binary
- packages.
+ If you are using <tt>debhelper</tt>, the
+ <prgn>dh_shlibdeps</prgn> program will do this work for you.
+ It will also correctly handle multi-binary packages.
</footnote>
</p>
field in the control file for this to work.
</p>
- <p>
- If <prgn>dpkg-shlibdeps</prgn> doesn't complain, you're
- done. If it does complain you might need to create your own
- <file>debian/shlibs.local</file> file, as explained below (see
- <ref id="shlibslocal">).
- </p>
-
<p>
If you have multiple binary packages, you will need to call
<prgn>dpkg-shlibdeps</prgn> on each one which contains
you will need to specify that <prgn>dpkg-shlibdeps</prgn>
should use the dependency line of type <tt>udeb</tt> by
adding the <tt>-tudeb</tt> option<footnote>
- <prgn>dh_shlibdeps</prgn> from the <tt>debhelper</tt> suite
- will automatically add this option if it knows it is
- processing a udeb.
- </footnote>. If there is no dependency line of type <tt>udeb</tt>
- in the <file>shlibs</file> file, <prgn>dpkg-shlibdeps</prgn> will
- fall back to the regular dependency line.
+ <prgn>dh_shlibdeps</prgn> from the <tt>debhelper</tt> suite
+ will automatically add this option if it knows it is
+ processing a udeb.
+ </footnote>. If there is no dependency line of
+ type <tt>udeb</tt> in the <file>shlibs</file>
+ file, <prgn>dpkg-shlibdeps</prgn> will fall back to the regular
+ dependency line.
</p>
<p>
- For more details on dpkg-shlibdeps, please see
+ For more details on <prgn>dpkg-shlibdeps</prgn>, please see
<ref id="pkg-dpkg-shlibdeps"> and
<manref name="dpkg-shlibdeps" section="1">.
</p>
usually of the form
<tt><var>name</var>.so.<var>major-version</var></tt>, in our
example, <tt>libz.so.1</tt>.<footnote>
- This can be determined using the command
- <example compact="compact">
+ This can be determined using the command
+ <example compact="compact">
objdump -p /usr/lib/libz.so.1.1.3 | grep SONAME
- </example>
+ </example>
</footnote>
The version part is the part which comes after
- <tt>.so.</tt>, so in our case, it is <tt>1</tt>.
+ <tt>.so.</tt>, so in our case, it is <tt>1</tt>. The soname may
+ instead be of the form
+ <tt><var>name</var>-<var>major-version</var>.so</tt>, such
+ as <tt>libdb-4.8.so</tt>, in which case the name would
+ be <tt>libdb</tt> and the version would be <tt>4.8</tt>.
</p>
<p>
<file>shlibs</file> file in the control area directly from
<file>debian/rules</file> without using a <file>debian/shlibs</file>
file at all,<footnote>
- This is what <prgn>dh_makeshlibs</prgn> in the
- <tt>debhelper</tt> suite does. If your package also has a udeb
- that provides a shared library, <prgn>dh_makeshlibs</prgn> can
- automatically generate the <tt>udeb:</tt> lines if you specify
- the name of the udeb with the <tt>--add-udeb</tt> option.
+ This is what <prgn>dh_makeshlibs</prgn> in
+ the <package>debhelper</package> suite does. If your package
+ also has a udeb that provides a shared
+ library, <prgn>dh_makeshlibs</prgn> can automatically generate
+ the <tt>udeb:</tt> lines if you specify the name of the udeb
+ with the <tt>--add-udeb</tt> option.
</footnote>
since the <file>debian/shlibs</file> file itself is ignored by
<prgn>dpkg-shlibdeps</prgn>.
packages.
</p>
</sect1>
-
- <sect1 id="shlibslocal">
- <heading>Writing the <file>debian/shlibs.local</file> file</heading>
-
- <p>
- This file is intended only as a <em>temporary</em> fix if
- your binaries or libraries depend on a library whose package
- does not yet provide a correct <file>shlibs</file> file.
- </p>
-
- <p>
- We will assume that you are trying to package a binary
- <tt>foo</tt>. When you try running
- <prgn>dpkg-shlibdeps</prgn> you get the following error
- message (<tt>-O</tt> displays the dependency information on
- <tt>stdout</tt> instead of writing it to
- <tt>debian/substvars</tt>, and the lines have been wrapped
- for ease of reading):
- <example compact="compact">
-$ 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)
- </example>
- You can then run <prgn>ldd</prgn> on the binary to find the
- full location of the library concerned:
- <example compact="compact">
-$ 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)
- </example>
- So the <prgn>foo</prgn> binary depends on the
- <prgn>libbar</prgn> shared library, but no package seems to
- provide a <file>*.shlibs</file> file handling
- <file>libbar.so.1</file> in <file>/var/lib/dpkg/info/</file>. Let's
- determine the package responsible:
- <example compact="compact">
-$ dpkg -S /usr/lib/libbar.so.1
-bar1: /usr/lib/libbar.so.1
-$ dpkg -s bar1 | grep Version
-Version: 1.0-1
- </example>
- This tells us that the <tt>bar1</tt> package, version 1.0-1,
- is the one we are using. Now we can file a bug against the
- <tt>bar1</tt> package and create our own
- <file>debian/shlibs.local</file> to locally fix the problem.
- Including the following line into your
- <file>debian/shlibs.local</file> file:
- <example compact="compact">
-libbar 1 bar1 (>= 1.0-1)
- </example>
- should allow the package build to work.
- </p>
-
- <p>
- As soon as the maintainer of <tt>bar1</tt> provides a
- correct <file>shlibs</file> file, you should remove this line
- from your <file>debian/shlibs.local</file> file. (You should
- probably also then have a versioned <tt>Build-Depends</tt>
- on <tt>bar1</tt> to help ensure that others do not have the
- same problem building your package.)
- </p>
- </sect1>
-
</sect>
-
</chapt>