+ the libraries and the symbols in those libraries directly
+ needed by the binaries or shared libraries in the package.
+ </footnote>
+ To do this, put a call to <prgn>dpkg-shlibdeps</prgn> into
+ your <file>debian/rules</file> file in the source package.
+ List all of the compiled binaries, libraries, or loadable
+ modules in your package.<footnote>
+ The easiest way to call <prgn>dpkg-shlibdeps</prgn>
+ correctly is to use a package helper framework such
+ as <package>debhelper</package>. If you are
+ using <package>debhelper</package>,
+ the <prgn>dh_shlibdeps</prgn> program will do this work for
+ you. It will also correctly handle multi-binary packages.
+ </footnote>
+ <prgn>dpkg-shlibdeps</prgn> will use the <file>symbols</file>
+ or <file>shlibs</file> files installed by the shared libraries
+ to generate dependency information. The package must then
+ provide a substitution variable into which the discovered
+ dependency information can be placed.
+ </p>
+
+ <p>
+ If you are creating a udeb for use in the Debian Installer,
+ 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.
+ </p>
+
+ <p>
+ <prgn>dpkg-shlibdeps</prgn> puts the dependency information
+ into the <file>debian/substvars</file> file by default, which
+ is then used by <prgn>dpkg-gencontrol</prgn>. You will need
+ to place a <tt>${shlibs:Depends}</tt> variable in
+ the <tt>Depends</tt> field in the control file of every binary
+ package built by this source package that contains compiled
+ binaries, libraries, or loadable modules. If you have
+ multiple binary packages, you will need to
+ call <prgn>dpkg-shlibdeps</prgn> on each one which contains
+ compiled libraries or binaries. For example, you could use
+ the <tt>-T</tt> option to the <tt>dpkg</tt> utilities to
+ specify a different <file>substvars</file> file for each
+ binary package.<footnote>
+ Again, <prgn>dh_shlibdeps</prgn>
+ and <prgn>dh_gencontrol</prgn> will handle everything except
+ the addition of the variable to the control file for you if
+ you're using <package>debhelper</package>, including
+ generating separate <file>substvars</file> files for each
+ binary package and calling <prgn>dpkg-gencontrol</prgn> with
+ the appropriate flags.
+ </footnote>
+ </p>
+
+ <p>
+ For more details on <prgn>dpkg-shlibdeps</prgn>,
+ see <manref name="dpkg-shlibdeps" section="1">.
+ </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, 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, but not the libraries it only uses
+ indirectly. The dependencies for the libraries used
+ directly will automatically pull in the indirectly-used
+ libraries. <prgn>dpkg-shlibdeps</prgn> will handle this logic
+ automatically, but package maintainers need to be aware of
+ this distinction between directly and indirectly using a
+ library if they have to override its results for some reason.
+ <footnote>
+ A good example of where this helps is the following. We
+ could update <tt>libimlib</tt> with a new version that
+ supports a new revision of a graphics format called dgf (but
+ retaining the same major version number) and depends on a
+ new library package <package>libdgf4</package> instead of
+ the older <package>libdgf3</package>. 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 <package>libdgf4</package> in order
+ to retire the older <package>libdgf3</package> package.
+ 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 an appropriate version
+ of <tt>libdgf</tt> and do not need rebuilding.
+ </footnote>
+ </p>
+ </sect1>
+
+ <sect1 id="sharedlibs-updates">
+ <heading>Shared library ABI changes</heading>
+
+ <p>
+ Maintaining a shared library package using
+ either <file>symbols</file> or <file>shlibs</file> files
+ requires being aware of the exposed ABI of the shared library
+ and any changes to it. Both <file>symbols</file>
+ and <file>shlibs</file> files record every change to the ABI
+ of the shared library; <file>symbols</file> files do so per
+ public symbol, whereas <file>shlibs</file> files record only
+ the last change for the entire library.
+ </p>
+
+ <p>
+ There are two types of ABI changes: ones that are
+ backward-compatible and ones that are not. An ABI change is
+ backward-compatible if any reasonable program or library that
+ was linked with the previous version of the shared library
+ will still work correctly with the new version of the shared
+ library.<footnote>
+ An example of an "unreasonable" program is one that uses
+ library interfaces that are documented as internal and
+ unsupported. If the only programs or libraries affected by
+ a change are "unreasonable" ones, other techniques, such as
+ declaring <tt>Breaks</tt> relationships with affected
+ packages or treating their usage of the library as bugs in
+ those packages, may be appropriate instead of changing the
+ SONAME. However, the default approach is to change the
+ SONAME for any change to the ABI that could break a program.
+ </footnote>
+ Adding new symbols to the shared library is a
+ backward-compatible change. Removing symbols from the shared
+ library is not. Changing the behavior of a symbol may or may
+ not be backward-compatible depending on the change; for
+ example, changing a function to accept a new enum constant not
+ previously used by the library is generally
+ backward-compatible, but changing the members of a struct that
+ is passed into library functions is generally not unless the
+ library takes special precautions to accept old versions of
+ the data structure.
+ </p>
+
+ <p>
+ ABI changes that are not backward-compatible normally require
+ changing the <tt>SONAME</tt> of the library and therefore the
+ shared library package name, which forces rebuilding all
+ packages using that shared library to update their
+ dependencies and allow them to use the new version of the
+ shared library. For more information,
+ see <ref id="sharedlibs-runtime">. The remainder of this
+ section will deal with backward-compatible changes.
+ </p>
+
+ <p>
+ Backward-compatible changes require either updating or
+ recording the <var>minimal-version</var> for that symbol
+ in <file>symbols</file> files or updating the version in
+ the <var>dependencies</var> in <file>shlibs</file> files. For
+ more information on how to do this in the two formats, see
+ <ref id="symbols"> and <ref id="shlibs">. Below are general
+ rules that apply to both files.
+ </p>
+
+ <p>
+ The easy case is when a public symbol is added. Simply add
+ the version at which the symbol was introduced
+ (for <file>symbols</file> files) or update the dependency
+ version (for <file>shlibs</file>) files. But special care
+ should be taken to update dependency versions when the
+ behavior of a public symbol changes. This is easy to neglect,
+ since there is no automated method of determining such
+ changes, but failing to update versions in this case may
+ result in binary packages with too-weak dependencies that will
+ fail at runtime, possibly in ways that can cause security
+ vulnerabilities. If the package maintainer believes that a
+ symbol behavior change may have occurred but isn't sure, it's
+ safer to update the version rather than leave it unmodified.
+ This may result in unnecessarily strict dependencies, but it
+ ensures that packages whose dependencies are satisfied will
+ work properly.
+ </p>
+
+ <p>
+ A common example of when a change to the dependency version
+ is required is a function that takes an enum or struct
+ argument that controls what the function does. For example:
+ <example>
+ enum library_op { OP_FOO, OP_BAR };
+ int library_do_operation(enum library_op);
+ </example>
+ If a new operation, <tt>OP_BAZ</tt>, is added,
+ the <var>minimal-version</var>
+ of <tt>library_do_operation</tt> (for <file>symbols</file>
+ files) or the version in the dependency for the shared library
+ (for <file>shlibs</file> files) must be increased to the
+ version at which <tt>OP_BAZ</tt> was introduced. Otherwise, a
+ binary built against the new version of the library (having
+ detected at compile-time that the library
+ supports <tt>OP_BAZ</tt>) may be installed with a shared
+ library that doesn't support <tt>OP_BAZ</tt> and will fail at
+ runtime when it tries to pass <tt>OP_BAZ</tt> into this
+ function.
+ </p>
+
+ <p>
+ Dependency versions in either <file>symbols</file>
+ or <file>shlibs</file> files normally should not contain the
+ Debian revision of the package, since the library behavior is
+ normally fixed for a particular upstream version and any
+ Debian packaging of that upstream version will have the same
+ behavior. In the rare case that the library behavior was
+ changed in a particular Debian revision, appending <tt>~</tt>
+ to the end of the version that includes the Debian revision is
+ recommended, since this allows backports of the shared library
+ package using the normal backport versioning convention to
+ satisfy the dependency.
+ </p>
+ </sect1>
+
+ <sect1 id="sharedlibs-symbols">
+ <heading>The <tt>symbols</tt> system</heading>
+
+ <p>
+ In the following sections, we will first describe where the
+ various <file>symbols</file> files are to be found, then
+ the <file>symbols</file> file format, and finally how to
+ create <file>symbols</file> files if your package contains a
+ shared library.
+ </p>
+
+ <sect2 id="symbols-paths">
+ <heading>The <file>symbols</file> files present on the
+ system</heading>
+
+ <p>
+ <file>symbols</file> files for a shared library are normally
+ provided by the shared library package as a control file,
+ but there are several override paths that are checked first
+ in case that information is wrong or missing. The following
+ list gives them in the order in which they are read
+ by <prgn>dpkg-shlibdeps</prgn> The first one that contains
+ the required information is used.
+ <list>
+ <item>
+ <p><file>debian/*/DEBIAN/symbols</file></p>
+
+ <p>
+ During the package build, if the package itself
+ contains shared libraries with <file>symbols</file>
+ files, they will be generated in these staging
+ directories by <prgn>dpkg-gensymbols</prgn>
+ (see <ref id="providing-symbols">). <file>symbols</file>
+ files found in the build tree take precedence
+ over <file>symbols</file> files from other binary
+ packages.
+ </p>
+
+ <p>
+ These files must exist
+ before <prgn>dpkg-shlibdeps</prgn> is run or the
+ dependencies of binaries and libraries from a source
+ package on other libraries from that same source
+ package will not be correct. In practice, this means
+ that <prgn>dpkg-gensymbols</prgn> must be run
+ before <prgn>dpkg-shlibdeps</prgn> during the package
+ build.<footnote>
+ An example may clarify. Suppose the source
+ package <tt>foo</tt> generates two binary
+ packages, <tt>libfoo2</tt> and <tt>foo-runtime</tt>.
+ When building the binary packages, the contents of
+ the packages are staged 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 contain
+ a <tt>symbols</tt> file, which will be installed
+ in <file>debian/libfoo2/DEBIAN/symbols</file>,
+ eventually to be included as a control file in that
+ package. 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/symbols</file> file
+ to determine whether <tt>foo-prog</tt>'s library
+ dependencies are satisfied by any of the libraries
+ provided by <tt>libfoo2</tt>. Since those binaries
+ were linked against the just-built shared library as
+ part of the build process, the <file>symbols</file>
+ file for the newly-built <tt>libfoo2</tt> must take
+ precedence over a <file>symbols</file> file for any
+ other <tt>libfoo2</tt> package already installed on
+ the system.
+ </footnote>
+ </p>
+ </item>
+
+ <item>
+ <p>
+ <file>/etc/dpkg/symbols/<var>package</var>.symbols.<var>arch</var></file>
+ and <file>/etc/dpkg/symbols/<var>package</var>.symbols</file>
+ </p>
+
+ <p>
+ Per-system overrides of shared library dependencies.
+ These files normally do not exist. They are
+ maintained by the local system administrator and must
+ not be created by any Debian package.
+ </p>
+ </item>
+
+ <item>
+ <p><file>symbols</file> control files for packages
+ installed on the system</p>
+
+ <p>
+ The <file>symbols</file> control files for all the
+ packages currently installed on the system are
+ searched last. This will be the most common source of
+ shared library dependency information. These are
+ normally found
+ in <file>/var/lib/dpkg/info/*.symbols</file>, but
+ packages should not rely on this and instead should
+ use <tt>dpkg-query --control-path <var>package</var>
+ symbols</tt> if for some reason these files need to be
+ examined.
+ </p>
+ </item>
+ </list>