FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian dpkg

 
 
LinkBack Thread Tools
 
Old 01-14-2012, 03:49 AM
Charles Plessy
 
Default Bug#571776: document symbols

Dear Russ and Raphaël,

here are some comments about the current patch. I agree with the other changes
made subsequently in that thread.


> + 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. These dependencies must be added to the binary
> + package when it is built, since they may change based on which
> + version of a shared library the binary or library was linked
> + with.

I have a difficulty with that sentence : isn't the goal of the symbols system
to actually avoid that a dependancy changes when a package is built on a newer
version of a library ? What rather changes is that the dependancy is modified
when a new version of the package makes new calls to the library, which may
have been implemented only in newer versions of the library.

If the misunderstanding is on my side, please consider it a hint that the
explanations can be expanded [PS: after reading the whole patch, maybe
this has something to do with minimal-version ?]


> + <p>
> + When a package that contains any shared libraries or compiled
> + binaries is built, it must run <prgn>dpkg-shlibdeps</prgn> on
> + each shared library and compiled binary to determine the
> + libraries used and hence the dependencies needed by the
> + package.<footnote>
> + <prgn>dpkg-shlibdeps</prgn> will use a program
> + like <prgn>objdump</prgn> or <prgn>readelf</prgn> to find the
> + libraries and the symbols in those libraries directly needed
> + by the binaries or shared libraries in the package.
> + </footnote>
> + </p>

(I understand that this is carried over from 3.9.2, but…) Just running
dpkg-shlibdeps is not enough, as this program only populates debian/substvars.
This is actually documented later in this chapter, which makes this paragraph
redundant. If its purpose is to lock the use of dpkg-shlibdeps and prevent
parallel implementations, it could be slimmed as follows.

<p>
Packages that contain any shared libraries or compiled binaries must
determine their dependencies by using the <prgn>dpkg-shlibdeps</prgn>
program and the <qref id="substvars"><tt>${shlibsepends}</tt></qref>
substvar. See <ref id="dpkg-shlibdeps"> for detailed instructions.
</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>. <file>symbols</file>

With a linear reading, it is the first time dpkg-gensymbols appears in the
Policy. How about linking to the "symbols" section, that gives a few more
words and refers to the manual page ?


> + <p>
> + If your package contains any compiled binaries or shared
> + libraries, put a call to <prgn>dpkg-shlibdeps</prgn> into
> + your <file>debian/rules</file> file in the source package.

The footnote removed above could be added here:

<footnote>
<prgn>dpkg-shlibdeps</prgn> will use a program
like <prgn>objdump</prgn> or <prgn>readelf</prgn> to find the
libraries and the symbols in those libraries directly needed
by the binaries or shared libraries in the package.
</footnote>


> + <p>
> + This command puts the dependency information into
> + the <file>debian/substvars</file> file, which is then used
> + by <prgn>dpkg-gencontrol</prgn>.

I propose to mitigate this by adding “by default”, because when using
debhelper, which is very frequent, debian/substvars is actually not used. (It
took me hours to understand why I could not populate new substvars in
debian/control by simply adding their values in debian/substvars in my
debhelper-managed packages).


> - <sect1 id="pkg-dpkg-shlibdeps">
> - <heading>
> - <prgn>dpkg-shlibdeps</prgn> - calculates shared library
> - dependencies
> - </heading>

I propose to keep a placeholder so that the next subsections are not
renumbered. Once all these sections are trimmed, we could consider removing
the appendix altogether.


Have a nice day,

--
Charles Plessy
Tsurumi, Kanagawa, Japan


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 20120114044940.GD9010@merveille.plessy.net">http://lists.debian.org/20120114044940.GD9010@merveille.plessy.net
 
Old 01-14-2012, 04:02 AM
Russ Allbery
 
Default Bug#571776: document symbols

Charles Plessy <plessy@debian.org> writes:

> here are some comments about the current patch. I agree with the other
> changes made subsequently in that thread.

>> + 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. These dependencies must be added to the binary
>> + package when it is built, since they may change based on which
>> + version of a shared library the binary or library was linked
>> + with.

> I have a difficulty with that sentence : isn't the goal of the symbols
> system to actually avoid that a dependancy changes when a package is
> built on a newer version of a library ? What rather changes is that the
> dependancy is modified when a new version of the package makes new calls
> to the library, which may have been implemented only in newer versions
> of the library.

That's true, but somewhat deceptive because this can happen with no
changes to the client code. In some cases, changes only to the library
with no changes to the client code can require tighter dependencies when
the client is built against the newer library. The obvious example is
replacing a macro in a header with an actual function entry point. In
this case, the client code will build and work fine with either the older
or the newer version of the library, but when built against the newer
library, it won't work with the older library.

That's what this is trying to capture here. If the exact same code is
rebuilt against a newer version of a library, it may have to depend on
that newer version of the library.

> If the misunderstanding is on my side, please consider it a hint that
> the explanations can be expanded [PS: after reading the whole patch,
> maybe this has something to do with minimal-version ?]

I'm not really sure what else to say, but I'm happy to add more if someone
can take a shot at letting me know what's needed....

But I was intentionally trying to keep this vague and not get into
enumerating the reasons why dependencies may need to be tightened. That's
really a topic for a whole separate guide on how shared libraries should
be packaged.

The rest of your changes look good, although I haven't had a chance to
incorporate them yet. I'll take a look, hopefully soon, although I may
not have time this weekend (which is a long holiday weekend in the US).

--
Russ Allbery (rra@debian.org) <http://www.eyrie.org/~eagle/>


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 87boq6512a.fsf@windlord.stanford.edu">http://lists.debian.org/87boq6512a.fsf@windlord.stanford.edu
 
Old 01-14-2012, 06:42 AM
Cyril Brulebois
 
Default Bug#571776: document symbols

Russ Allbery <rra@debian.org> (13/01/2012):
> Yes, but there was some discussion in the Policy bug asking why shlibs
> files were required when they're not used if a symbols file is present,
> and while I originally argued that keeping them both made sense, I came
> around to that position after reviewing the bug discussion. It doesn't
> hurt anything, but there doesn't really seem to be any point in providing
> shlibs if symbols is present.

Last I checked, one needs an shlibs file to get proper dependencies into
udebs, which explains why libx* packages still use some -V flag in their
dh_makeshlibs call.

Demo: xorg-server/experimental build-depends on libpciaccess (>= version-
in-unstable), and the symbols added in this version are really needed (see
below).

Rebuilding libpciaccess to drop the -V flag, and rebuilding xorg-server
against it generates this change in xserver-xorg-core-udeb's dependencies:
| Depends: […], [-libpciaccess0-udeb (>= 0.12.902),-] {+libpciaccess0-udeb,+} […]

→ Fail.


“Those new symbols really are needed”:
| $ grep 902 ../lib/libpciaccess.git/debian/*symbols
| pci_device_map_legacy@Base 0.12.902
| pci_device_unmap_legacy@Base 0.12.902
| $ for i in $(find debian/xserver-xorg-core-udeb -type f); do if nm -D $i 2>&1|grep -qs pci_device_'.*'map_legacy; then echo $i; fi; done
| debian/xserver-xorg-core-udeb/usr/lib/xorg/modules/libvgahw.so
| debian/xserver-xorg-core-udeb/usr/lib/xorg/modules/libint10.so

Diff in the libpciaccess package to exhibit that:
| - dh_makeshlibs -V'libpciaccess0 (>= 0.12.902)' --add-udeb=$(PACKAGE)-udeb -- -c4
| + dh_makeshlibs --add-udeb=$(PACKAGE)-udeb -- -c4

Mraw,
KiBi.
 
Old 01-14-2012, 06:45 AM
Russ Allbery
 
Default Bug#571776: document symbols

Cyril Brulebois <kibi@debian.org> writes:
> Russ Allbery <rra@debian.org> (13/01/2012):

>> Yes, but there was some discussion in the Policy bug asking why shlibs
>> files were required when they're not used if a symbols file is present,
>> and while I originally argued that keeping them both made sense, I came
>> around to that position after reviewing the bug discussion. It doesn't
>> hurt anything, but there doesn't really seem to be any point in
>> providing shlibs if symbols is present.

> Last I checked, one needs an shlibs file to get proper dependencies into
> udebs, which explains why libx* packages still use some -V flag in their
> dh_makeshlibs call.

Yes, udebs are called out as an exception and it's still stated that
shlibs must be used for udebs. They still are consistent with the
property above, though, since symbols aren't supported for udebs, or at
least that's what I understood.

--
Russ Allbery (rra@debian.org) <http://www.eyrie.org/~eagle/>


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 87obu63ey2.fsf@windlord.stanford.edu">http://lists.debian.org/87obu63ey2.fsf@windlord.stanford.edu
 
Old 03-17-2012, 05:17 PM
Russ Allbery
 
Default Bug#571776: document symbols

Here is a new proposed patch that incorporates the feedback to date with
some other, substantial changes.

It's apparent to me from hands-on experimentation with C++ libraries that,
at least at the moment, shlibs is likely to have an ongoing existence in
the archive. Accordingly, some of the layout decisions I made to keep the
shlibs section separate in a way that would let it potentially be dropped
later weren't a good idea. This version therefore substantially
reorganizes and somewhat expands the documentation to:

* Describe the difference between symbols and shlibs in more detail and
provide advice on how to choose between them.

* Document calling dpkg-shlibdeps in a separate section independent of
either symbols or shlibs, since the details of how to use it doesn't
vary based on the dependency system in play.

* Provide separate documentation for how to handle ABI changes and
determine dependency versions independent of either system, since the
same process should be used either way. The only difference between the
systems is whether the version information is per-symbol or per-library.

* Move the symbols and shlibs documentation to subsections of the general
section on shared library dependency management.

* Move the information on how to determine the soversion out of the shlibs
section and to the runtime shared library section so that it is next to
the discussion of shared library package names. The shlibs
documentation now just references it.

Due to the reformatting, the diff is even longer and is now really just
the complete removal of the current shlibs section followed by the
addition of the new section. I'm therefore including here the complete
SGML source of that section not in diff format, followed by the diff of
everything *outside* of that section. I think this will be easier to
review.

<sect id="sharedlibs-depends">
<heading>Dependencies between the library and other
packages</heading>

<p>
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. These dependencies must be added to the binary
package when it is built, since they may change based on which
version of a shared library the binary or library was linked
with even if there are no changes to the source of the binary
(for example, symbol versions change, macros become functions or
vice versa, or the binary package may determine at compile-time
whether new library interfaces are available and can be called).
To allow these dependencies to be constructed, shared libraries
must provide either a <file>symbols</file> file or
a <file>shlibs</file> file, which provide information on the
package dependencies required to ensure the presence of this
library. Any package which uses a shared library must use these
files to determine the required dependencies when it is built.
</p>

<p>
These two mechanisms differ in the degree of detail that they
provide. A <file>symbols</file> file documents every symbol
that is part of the library ABI and, for each, the version of
the package in which it was introduced. This permits detailed
analysis of the symbols used by a particular package and
construction of an accurate dependency, but it requires the
package maintainer to track more information about the shared
library. A <file>shlibs</file> file, in contrast, only
documents the last time the library ABI changed in any way. It
only provides information about the library as a whole, not
individual symbols. When a package is built using a shared
library with only a <file>shlibs</file> file, the generated
dependency will require a version of the shared library equal to
or newer than the version of the last ABI change. This
generates unnecessarily restrictive dependencies compared
to <file>symbols</file> files if none of the symbols used by the
package have changed. This, in turn, may make upgrades
needlessly complex and unnecessarily restrict use of the package
on systems with older versions of the shared libraries.
</p>

<p>
<file>shlibs<file> files also have a flawed representation of
library SONAMEs, making it difficult to use <file>shlibs</file>
files in some unusual corner cases.
</p>

<p>
<file>symbols</file> files are therefore recommended for most
shared library packages since they provide more accurate
dependencies. For most C libraries, the additional detail
required by <file>symbols</file> files is not too difficult to
maintain. However, maintaining exhaustive symbols information
for a C++ library can be quite onerous, so <file>shlibs</file>
files may be more appropriate for most C++ libraries. udebs
must also use <file>shlibs</file>, since the udeb infrastructure
does not use <file>symbols</file>.
</p>

<sect1 id="dpkg-shlibdeps">
<heading>Generating dependencies on shared libraries</heading>

<p>
When a package that contains any shared libraries or compiled
binaries is built, it must run <prgn>dpkg-shlibdeps</prgn> on
each shared library and compiled binary to determine the
libraries used and hence the dependencies needed by the
package.<footnote>
<prgn>dpkg-shlibdeps</prgn> will use a program
like <prgn>objdump</prgn> or <prgn>readelf</prgn> to find
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>${shlibsepends}</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, using 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
indirectly uses. 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 binary was linked with the previous
version of the shared library will still work correctly with
the new version of the shared library. 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 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, 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>
</p>

<p>
Be aware that if a <file>debian/shlibs.local</file> exists
in the source package, it will override
any <file>symbols</file> files. This is the only case where
a <file>shlibs</file> is used despite <file>symbols</file>
files being present. See <ref id="shlibs-paths">
and <ref id="sharedlibs-shlibdeps"> for more information.
</p>
</sect2>

<sect2 id="symbols">
<heading>The <file>symbols</file> File Format</heading>

<p>
The following documents the format of
the <file>symbols</file> control file as included in binary
packages. These files are built from
template <file>symbols</file> files in the source package
by <prgn>dpkg-gensymbols</prgn>. The template files support
a richer syntax that allows <prgn>dpkg-gensymbols</prgn> to
do some of the tedious work involved in
maintaining <file>symbols</file> files, such as handling C++
symbols or optional symbols that may not exist on particular
architectures. When writing <file>symbols</file> files for
a shared library package, refer
to <manref name="dpkg-gensymbols" section="1"> for the
richer syntax.
</p>

<p>
A <file>symbols</file> may contain one or more entries, one
for each shared library contained in the package
corresponding to that <file>symbols</file>. Each entry has
the following format:
</p>

<p>
<example>
<var>library-soname</var> <var>main-dependency-template</var>
[| <var>alternative-dependency-template</var>]
[...]
[* <var>field-name</var>: <var>field-value</var>]
[...]
<var>symbol</var> <var>minimal-version</var>[ <var>id-of-dependency-template</var> ]
</example>
</p>

<p>
To explain this format, we'll use the the <tt>zlib1g</tt>
package as an example, which (at the time of writing)
installs the shared
library <file>/usr/lib/libz.so.1.2.3.4</file>. Mandatory
lines will be described first, followed by optional lines.
</p>

<p>
<var>library-soname</var> must contain exactly the value of
the ELF <tt>SONAME</tt> attribute of the shared library. In
our example, this is <tt>libz.so.1</tt>.<footnote>
This can be determined by using the command
<example compact="compact">
readelf -d /usr/lib/libz.so.1.2.3.4 | grep SONAME
</example>
</footnote>
</p>

<p>
<var>main-dependency-template</var> has the same syntax as a
dependency field in a binary package control file, except
that the string <tt>#MINVER#</tt> is replaced by a version
restriction like <tt>(>= <var>version</var>)</tt> or by
nothing if an unversioned dependency is deemed sufficient.
The version restriction will be based on which symbols from
the shared library are referenced and the version at which
they were introduced (see below). In nearly all
cases, <var>main-dependency-template</var> will
be <tt><var>package</var> #MINVER#</tt>,
where <var>package</var> is the name of the binary package
containing the shared library. This adds a simple,
possibly-versioned dependency on the shared library package.
In some rare cases, such as when multiple packages provide
the same shared library ABI, the dependency template may
need to be more complex.
</p>

<p>
In our example, the first line of
the <tt>zlib1g</tt> <file>symbols</file> file would be:
<example compact="compact">
libz.so.1 zlib1g #MINVER#
</example>
</p>

<p>
Each public symbol exported by the shared library must have
a corresponding symbol line, indented by one
space. <var>symbol</var> is the exported symbol (which, for
C++, means the mangled symbol) followed by <tt>@</tt> and
the symbol version, or the string <tt>Base</tt> if there is
no symbol version. <var>minimal-version</var> is the most
recent version of the shared library that changed the
behavior of that symbol, whether by adding it, changing its
function signature (the parameters, their types, or the
return type), or its behavior in a way that is visible to a
caller. <var>id-of-dependency-template</var> is an optional
field that references
an <var>alternative-dependency-template</var>; see below for
a full description.
</p>

<p>
For example, <tt>libz.so.1</tt> contains the
symbols <tt>compress</tt>
and <tt>compressBound</tt>. <tt>compress</tt> has no symbol
version and last changed its behavior in upstream
version <tt>1:1.1.4</tt>. <tt>compressBound</tt> has the
symbol version <tt>ZLIB_1.2.0</tt>, was introduced in
upstream version <tt>1:1.2.0</tt>, and has not changed its
behavior. Its <file>symbols</file> file therefore contains
the lines:
<example compact="compact">
compress@Base 1:1.1.4
compressBound@ZLIB_1.2.0 1:1.2.0
</example>
Packages using only <tt>compress</tt> would then get a
dependency of <tt>zlib1g (>= 1:1.1.4)</tt>, but packages
using <tt>compressBound</tt> would get a dependency
of <tt>zlib1g (>= 1:1.2.0)</tt>.
</p>

<p>
One or more <var>alternative-dependency-template</var> lines
may be provided. These are used in cases where some symbols
in the shared library should use one dependency template
while others should use a different template. The
alternative dependency templates are used only if a symbol
line contains the <var>id-of-dependency-template</var>
field. The first alternative dependency template is
numbered 1, the second 2, and so forth.<footnote>
An example of where this may be needed is with a library
that implements the libGL interface. All GL
implementations provide the same set of base interfaces,
and then may provide some additional interfaces only used
by programs that require that specific GL implementation.
So, for example, libgl1-mesa-glx may use the
following <file>symbols</file> file:
<example>
libGL.so.1 libgl1
| libgl1-mesa-glx #MINVER#
publicGlSymbol@Base 6.3-1
[...]
implementationSpecificSymbol@Base 6.5.2-7 1
[...]
</example>
Binaries or shared libraries using
only <tt>publicGlSymbol</tt> would depend only
on <tt>libgl1</tt> (which may be provided by multiple
packages), but ones
using <tt>implementationSpecificSymbol</tt> would get a
dependency on <tt>libgl1-mesa-glx (>= 6.5.2-7)</tt>
</footnote>
</p>

<p>
Finally, the entry for the library may contain one or more
metadata fields. Currently, the only
supported <var>field-name</var>
is <tt>Build-Depends-Package</tt>, whose value lists
the <qref id="sharedlibs-dev">library development
package</qref> on which packages using this shared library
declare a build dependency. If this field is
present, <prgn>dpkg-shlibdeps</prgn> uses it to ensure that
the resulting binary package dependency on the shared
library is at least as strict as the source package
dependency on the shared library development
package.<footnote>
This field should normally not be necessary, since if the
behavior of any symbol has changed, the corresponding
symbol <var>minimal-version</var> should have been
increased. But including it makes the <tt>symbols</tt>
system more robust by tightening the dependency in cases
where the package using the shared library specifically
requires at least a particular version of the shared
library development package for some reason.
</footnote>
For our example, the <tt>zlib1g</tt> <file>symbols</file>
file would contain:
<example compact="compact">
* Build-Depends-Package: zlib1g-dev
</example>
</p>

<p>
Also see <manref name="deb-symbols" section="5">.
</p>
</sect2>

<sect2 id="providing-symbols">
<heading>Providing a <file>symbols</file> file</heading>

<p>
If your package provides a shared library, you should
arrange to include a <file>symbols</file> control file
following the format described above in that package. You
must include either a <file>symbols</file> control file or
a <file>shlibs</file> control file.
</p>

<p>
Normally, this is done by creating a <file>symbols</file> in
the source package
named <file>debian/<var>package</var>.symbols</file>
or <file>debian/symbols</file>, possibly
with <file>.<var>arch</var></file> appended if the symbols
information varies by architecture. This file may use the
extended syntax documented in <manref name="dpkg-gensymbols"
section="1">. Then, call <prgn>dpkg-gensymbols</prgn> as
part of the package build process. It will
create <file>symbols</file> files in the package staging
area based on the binaries and libraries in the package
staging area and the <file>symbols</file> files in the
source package.<footnote>
If you are
using <tt>debhelper</tt>, <prgn>dh_makeshlibs</prgn> will
take care of calling either <prgn>dpkg-gensymbols</prgn>
or generating a <file>shlibs</file> file as appropriate.
</footnote>
</p>

<p>
Packages that provide <file>symbols</file> files must keep
them up-to-date to ensure correct dependencies in packages
that use the shared libraries. This means updating
the <file>symbols</file> file whenever a new public symbol
is added, changing the <var>minimal-version</var> field
whenever a symbol changes behavior or signature in a
backward-compatible way (see <ref id="sharedlibs-updates">),
and changing the <var>library-soname</var>
and <var>main-dependency-template</var>, and probably all of
the <var>minimal-version</var> fields, when the library
changes <tt>SONAME</tt>. Removing a public symbol from
the <file>symbols</file> file because it's no longer
provided by the library normally requires changing
the <tt>SONAME</tt> of the library.
See <ref id="sharedlibs-runtime"> for more information
on <tt>SONAME</tt>s.
</p>
</sect2>
</sect1>

<sect1 id="sharedlibs-shlibdeps">
<heading>The <tt>shlibs</tt> system</heading>

<p>
The <tt>shlibs</tt> system is an simpler alternative to
the <tt>symbols</tt> system for declaring dependencies for
shared libraries. It may be more appropriate for C++
libraries and other cases where tracking individual symbols is
too difficult. It predated the <tt>symbols</tt> system and is
therefore frequently seen in older packages. It is also
required for udebs, which do not support <tt>symbols</tt>.
</p>

<p>
In the following sections, we will first describe where the
various <file>shlibs</file> files are to be found, then how to
use <prgn>dpkg-shlibdeps</prgn>, and finally
the <file>shlibs</file> file format and how to create them.
</p>

<sect2 id="shlibs-paths">
<heading>The <file>shlibs</file> files present on the
system</heading>

<p>
There are several places where <tt>shlibs</tt> files are
found. The following list gives them in the order in which
they are read by <prgn>dpkg-shlibdeps</prgn>. (The first
one which gives the required information is used.)
<list>
<item>
<p><file>debian/shlibs.local</file></p>

<p>
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. This file overrides information
obtained from any other source.
</p>
</item>

<item>
<p><file>/etc/dpkg/shlibs.override</file></p>

<p>
This lists global overrides. This list is normally
empty. It is maintained by the local system
administrator.
</p>
</item>

<item>
<p><file>DEBIAN/shlibs</file> files in the "build
directory"</p>

<p>
These files are generated as part of the package build
process and staged for inclusion as control files in
the binary packages being built. They provide details
of any shared libraries included in the same package.
</p>
</item>

<item>
<p><file>shlibs</file> control files for packages
installed on the system</p>

<p>
The <file>shlibs</file> control files for all the
packages currently installed on the system. 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>
shlibs</tt> if for some reason these files need to be
examined.
</p>
</item>

<item>
<p><file>/etc/dpkg/shlibs.default</file></p>

<p>
This file lists any shared libraries whose packages
have failed to provide correct <file>shlibs</file>
files. It was used when the <file>shlibs</file> setup
was first introduced, but it is now normally empty.
It is maintained by the <tt>dpkg</tt> maintainer.
</p>
</item>
</list>
</p>

<p>
If a <file>symbols</file> file for a shared library package
is available, <prgn>dpkg-shlibdeps</prgn> will always use it
in preference to a <file>shlibs</file>, with the exception
of <file>debian/shlibs.local</file>. The latter overrides
any other <file>shlibs</file> or <file>symbols</file> files.
</p>
</sect2>

<sect2 id="shlibs">
<heading>The <file>shlibs</file> File Format</heading>

<p>
Each <file>shlibs</file> file has the same format. Lines
beginning with <tt>#</tt> are considered to be comments and
are ignored. Each line is of the form:
<example compact="compact">
[<var>type</var>: ]<var>library-name</var> <var>soname-version</var> <var>dependencies ...</var>
</example>
</p>

<p>
We will explain this by reference to the example of the
<tt>zlib1g</tt> package, which (at the time of writing)
installs the shared
library <file>/usr/lib/libz.so.1.2.3.4</file>.
</p>

<p>
<var>type</var> is an optional element that indicates the
type of package for which the line is valid. The only type
currently in use is <tt>udeb</tt>. The colon and space
after the type are required.
</p>

<p>
<var>library-name</var> is the name of the shared library,
in this case <tt>libz</tt>. (This must match the name part
of the soname, see below.)
</p>

<p>
<var>soname-version</var> is the version part of the
ELF <tt>SONAME</tt> attribute of the library, determined the
same way that the <var>soversion</var> component of the
recommended shared library package name is determined.
See <ref id="sharedlibs-runtime"> for the details.
</p>

<p>
<var>dependencies</var> 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 <ref id="depsyntax"> for details on the
syntax, and <ref id="sharedlibs-updates"> for details on how
to maintain the dependency version constraint.
</p>

<p>
In our example, if the last change to the <tt>zlib1g</tt>
package that could change behavior for a client of that
library was in version <tt>1:1.2.3.3.dfsg-1</tt>, then
the <tt>shlibs</tt> entry for this library could say:
<example compact="compact">
libz 1 zlib1g (>= 1:1.2.3.3.dfsg-1)
</example>
This version restriction must be new enough that any binary
built against the current version of the library will work
with any version of the shared library that satisfies that
dependency.
</p>

<p>
As zlib1g also provides a udeb containing the shared
library, there would also be a second line:
<example compact="compact">
udeb: libz 1 zlib1g-udeb (>= 1:1.2.3.3.dfsg-1)
</example>
</p>
</sect2>

<sect2>
<heading>Providing a <file>shlibs</file> file</heading>

<p>
To provide a <file>shlibs</file> file for a shared library
binary package, create a <file>shlibs</file> file following
the format described above and place it in
the <file>DEBIAN</file> directory for that package during
the build. It will then be included as a control file for
that package<footnote>
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>.
</p>

<p>
Since <prgn>dpkg-shlibdeps</prgn> reads
the <file>DEBIAN/shlibs</file> files in all of the binary
packages being built from this source package, all of
the <file>DEBIAN/shlibs</file> files should be installed
before <prgn>dpkg-shlibdeps</prgn> is called on any of the
binary packages.
</p>
</sect2>
</sect1>
</sect>

diff --git a/policy.sgml b/policy.sgml
index 1a61d4f..57caf5d 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -848,10 +848,11 @@
Among those files are the package maintainer scripts
and <file>control</file>, the <qref id="binarycontrolfiles">binary
package control file</qref> that contains the control fields for
- the package. Other control information files
- include <qref id="sharedlibs-shlibdeps">the <file>shlibs</file>
- file</qref> used to store shared library dependency information
- and the <file>conffiles</file> file that lists the package's
+ the package. Other control information files include
+ the <qref id="sharedlibs-symbols"><file>symbols</file> file</qref>
+ or <qref id="sharedlibs-shlibdeps"><file>shlibs</file> file</qref>
+ used to store shared library dependency information and
+ the <file>conffiles</file> file that lists the package's
configuration files (described in <ref id="config-files">).
</p>

@@ -5493,17 +5494,29 @@ Replaces: mail-transport-agent
be placed in a package named
<package><var>libraryname</var><var>soversion</var></package>,
where <var>soversion</var> is the version number in
- the <tt>SONAME</tt> of the shared library.
- See <ref id="shlibs"> for detailed information on how to
- determine this version. Alternatively, if it would be confusing
- to directly append <var>soversion</var>
- to <var>libraryname</var> (if, for example, <var>libraryname</var>
- itself ends in a number), you should use
+ the <tt>SONAME</tt> of the shared library. Alternatively, if it
+ would be confusing to directly append <var>soversion</var>
+ to <var>libraryname</var> (if, for
+ example, <var>libraryname</var> itself ends in a number), you
+ should use
<package><var>libraryname</var>-<var>soversion</var></package>
instead.
</p>

<p>
+ To determine the <var>soversion</var>, look at
+ the <tt>SONAME</tt> of the library, stored in the
+ ELF <tt>SONAME</tt> attribute. it is usually of the
+ form <tt><var>name</var>.so.<var>major-version</var></tt> (for
+ example, <tt>libz.so.1</tt>). The version part is the part
+ which comes after <tt>.so.</tt>, so in that example 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-5.1.so</tt>, in which case the name would
+ be <tt>libdb</tt> and the version would be <tt>5.1</tt>.
+ </p>
+
+ <p>
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 all of their <tt>SONAME</tt>s will
@@ -5538,9 +5551,8 @@ Replaces: mail-transport-agent
linked against the old shared library. Correct versioning of
dependencies on the newer shared library by binaries that use
the new interfaces is handled via
- the <qref id="sharedlibs-shlibdeps"><tt>shlibs</tt>
- system</qref> or via symbols files (see
- <manref name="deb-symbols" section="5">).
+ the <qref id="sharedlibs-depends"><tt>symbols</tt>
+ or <tt>shlibs</tt> system</qref>.
</p>

<p>
@@ -7760,8 +8271,9 @@ INSTALL = install -s # (or use strip on the files in debian/tmp)
Although not enforced by the build tools, shared libraries
must be linked against all libraries that they use symbols from
in the same way that binaries are. This ensures the correct
- functioning of the <qref id="sharedlibs-shlibdeps">shlibs</qref>
- system and guarantees that all libraries can be safely opened
+ functioning of the <qref id="sharedlibs-symbols">symbols</qref>
+ and <qref id="sharedlibs-shlibdeps">shlibs</qref>
+ systems and guarantees that all libraries can be safely opened
with <tt>dlopen()</tt>. Packagers may wish to use the gcc
option <tt>-Wl,-z,defs</tt> when building a shared library.
Since this option enforces symbol resolution at build time,
@@ -10569,82 +11081,10 @@ END-INFO-DIR-ENTRY
</heading>

<p>
- This program is usually called from <file>debian/rules</file>
- just before <prgn>dpkg-gencontrol</prgn> (see <ref
- id="pkg-sourcetree">), in the top level of the source tree.
- </p>
-
- <p>
- Its arguments are executables and shared libraries
- <footnote>
- <p>
- They may be specified either in the locations in the
- source tree where they are created or in the locations
- in the temporary build tree where they are installed
- prior to binary package creation.
- </p>
- </footnote> for which shared library dependencies should
- be included in the binary package's control file.
- </p>
-
- <p>
- If some of the found shared libraries should only
- warrant a <tt>Recommends</tt> or <tt>Suggests</tt>, or if
- some warrant a <tt>Pre-Depends</tt>, this can be achieved
- by using the <tt>-d<var>dependency-field</var></tt> option
- before those executable(s). (Each <tt>-d</tt> option
- takes effect until the next <tt>-d</tt>.)
- </p>
-
- <p>
- <prgn>dpkg-shlibdeps</prgn> does not directly cause the
- output control file to be modified. Instead by default it
- adds to the <file>debian/substvars</file> file variable
- settings like <tt>shlibsepends</tt>. These variable
- settings must be referenced in dependency fields in the
- appropriate per-binary-package sections of the source
- control file.
- </p>
-
- <p>
- For example, a package that generates an essential part
- which requires dependencies, and optional parts that
- which only require a recommendation, would separate those
- two sets of dependencies into two different fields.<footnote>
- At the time of writing, an example for this was the
- <package/xmms/ package, with Depends used for the xmms
- executable, Recommends for the plug-ins and Suggests for
- even more optional features provided by unzip.
- </footnote>
- It can say in its <file>debian/rules</file>:
- <example>
- dpkg-shlibdeps -dDepends <var>program anotherprogram ...</var>
- -dRecommends <var>optionalpart anotheroptionalpart</var>
- </example>
- and then in its main control file <file>debian/control</file>:
- <example>
- <var>...</var>
- Depends: ${shlibsepends}
- Recommends: ${shlibs:Recommends}
- <var>...</var>
- </example>
- </p>
-
- <p>
- Sources which produce several binary packages with
- different shared library dependency requirements can use
- the <tt>-p<var>varnameprefix</var></tt> option to override
- the default <tt>shlibs:</tt> prefix (one invocation of
- <prgn>dpkg-shlibdeps</prgn> per setting of this option).
- They can thus produce several sets of dependency
- variables, each of the form
- <tt><var>varnameprefix</var>:<var>dependencyfield</var></tt>,
- which can be referred to in the appropriate parts of the
- binary package control files.
+ See <manref name="dpkg-shlibdeps" section="1">.
</p>
</sect1>

-
<sect1 id="pkg-dpkg-distaddfile">
<heading>
<prgn>dpkg-distaddfile</prgn> - adds a file to

--
Russ Allbery (rra@debian.org) <http://www.eyrie.org/~eagle/>


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 87aa3fum6e.fsf@windlord.stanford.edu">http://lists.debian.org/87aa3fum6e.fsf@windlord.stanford.edu
 
Old 03-20-2012, 01:28 AM
Charles Plessy
 
Default Bug#571776: document symbols

Le Sat, Mar 17, 2012 at 11:17:29AM -0700, Russ Allbery a crit :
> Here is a new proposed patch that incorporates the feedback to date with
> some other, substantial changes.

> Due to the reformatting, the diff is even longer and is now really just
> the complete removal of the current shlibs section followed by the
> addition of the new section. I'm therefore including here the complete
> SGML source of that section not in diff format, followed by the diff of
> everything *outside* of that section. I think this will be easier to
> review.

Hi Russ,

after reading your chages, I have not found potential problems or errors.

Have a nice day,

--
Charles


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 20120320022804.GC10507@falafel.plessy.net">http://lists.debian.org/20120320022804.GC10507@falafel.plessy.net
 
Old 03-20-2012, 07:52 PM
Julien Cristau
 
Default Bug#571776: document symbols

On Mon, Mar 19, 2012 at 17:26:04 -0500, Jonathan Nieder wrote:

> > These dependencies must be added to the binary
> > package when it is built, since they may change
>
> This means packages must not hard-code library dependencies. It
> also seems like good policy, but I suspect it would render packages
> such as chromium that use dlopen() and hard-code the corresponding
> library name in dependencies RC-buggy.
>
They're already broken.

> What about libraries like glib (assuming one only uses old symbols)
> that are never supposed to change soname?
>
What about them?

> [...]
> > To allow these dependencies to be constructed, shared libraries
> > must provide either a <file>symbols</file> file or
> > a <file>shlibs</file> file, which provide information on the
> > package dependencies required to ensure the presence of this
> > library.
>
> Subject/verb agreement: s/provide/provides/
>
> Clarity: s/this library/interfaces provided by this library/
>
> > <p>
> > These two mechanisms differ in the degree of detail that they
> > provide. A <file>symbols</file> file documents every symbol
> > that is part of the library ABI and, for each, the version of
> > the package in which it was introduced.
>
> Maybe, since minimal-version is not always the version in which the
> symbol was introduced:
>
> and, for each, a minimal version of the library needed to use
> that symbol, which is typically the version of the package in
> which it was introduced.
>
> [...]
> > <file>shlibs<file> files also have a flawed representation of
> > library SONAMEs, making it difficult to use <file>shlibs</file>
> > files in some unusual corner cases.
>
> I'm not sure what this passage is referring to. Can you say more?
> (Maybe in a footnote.)
>
libfooN.shlibs says 'libfoo N' not the actual SONAME, so if the SONAME
doesn't match one of the two expected formats (libfoo-N.so or
libfoo.so.N) it can't be represented.

> [...]
> > udebs
> > must also use <file>shlibs</file>, since the udeb infrastructure
> > does not use <file>symbols</file>.
>
> To avoid confusion it might be worth forbidding symbols files in
> udebs, or at least symbols files without a corresponding shlibs file
> accompanying them.
>
That makes no sense. udebs don't have those files, when building an
udeb the dependency information is read from the shlibs files of the
debs corresponding to the libraries you depend on.

> [...]
> > If you have
> > multiple binary packages, you will need to
> > call <prgn>dpkg-shlibdeps</prgn> on each one which contains
> > compiled libraries or binaries, using the <tt>-T</tt> option
> > to the <tt>dpkg</tt> utilities to specify a
> > different <file>substvars</file> file for each binary
> > package.<footnote>
>
> An alternative is to clear substvars between builds of different
> binary packages.
>
Who does that? I don't think it's necessary to document all the twisted
ways to make things not break.

> [...]
> > loads <tt>libbar</tt>. A package should depend on the
> > libraries it directly uses, but not the libraries it
> > indirectly uses.
>
> Pedantry: what if my package uses the same library both directly and
> indirectly? "but not the libraries it only uses indirectly" would
> avoid that question.
>
> > 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 binary was linked with the previous
> > version of the shared library will still work correctly with
> > the new version of the shared library. Adding new symbols to
> > the shared library is a backward-compatible change. Removing
> > symbols from the shared library is not.
>
> If I remove a symbol that was documented to be private or change
> the behavior of a function when given invalid arguments, is that a
> backward-compatible change?
>
> If I add change the implementation in such a way that the library
> becomes so large that some large programs cannot use it any more, is
> that a backward-incompatible change?
>
I'm not sure policy should go into such details. And anyway, that's
answered by the previous sentence (an incompatible change is one that
breaks reverse deps). The last two are simple examples.

Cheers,
Julien
 
Old 03-24-2012, 02:27 PM
"Bernhard R. Link"
 
Default Bug#571776: document symbols

* Russ Allbery <rra@debian.org> [120317 19:17]:
> These two mechanisms differ in the degree of detail that they
> provide. A <file>symbols</file> file documents every symbol
> that is part of the library ABI and, for each, the version of
> the package in which it was introduced. [...]

This is misleading. It's about when the symbol with its current meaning
was introduced but could be easily misunderstood to mean the first
introduction (and some people might not read the later explanations).

How about something like
| [...] A <file>symbols</file> file documents for each symbol
| exported by a library the minimal version of the package any
| binary using this symbol will need. [...]



> <file>shlibs<file> files also have a flawed representation of
> library SONAMEs, making it difficult to use <file>shlibs</file>
> files in some unusual corner cases.

Only stylistics: How about not using "flawed"? Something like
"Also the way library SONAMEs are represented in <file>shlibs<file>
files makes it difficult to use them in some unusual corner cases."?

Bernhard R. Link


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 20120324152733.GA20924@client.brlink.eu">http://lists.debian.org/20120324152733.GA20924@client.brlink.eu
 
Old 08-12-2012, 09:16 PM
Russ Allbery
 
Default Bug#571776: document symbols

Jonathan Nieder <jrnieder@gmail.com> writes:
> Jonathan Nieder wrote:

>> I'll reply with an interdiff relative to the last version of the
>> patch.

> Here it is.

And here is the interdiff between your patch and what I currently have, to
make it easier for you and anyone who was familiar with your version of
the patch to review what I further changed.

I'm going to reply to this thread in a moment with the whole current
patch, for hopefully the last time, and then we can try to get seconds and
(at least) merge this monster.

commit 97cb027db4afab774ea4f4ff9e7bef7a6dcbbda0
Author: Russ Allbery <rra@debian.org>
Date: Sun Aug 12 14:14:23 2012 -0700

Further wording changes on top of Jonathan Neider's work

Add a footnote explaining what a "reasonable" program is. Clarify
the shlibs versioning text. Other minor textual changes for
clarity.

diff --git a/policy.sgml b/policy.sgml
index 0965b76..fa1c39a 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -5978,11 +5978,11 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
whether new library interfaces are available and can be called).
To allow these dependencies to be constructed, shared libraries
must provide either a <file>symbols</file> file or
- a <file>shlibs</file> file, which provides information on the
+ a <file>shlibs</file> file. These provide information on the
package dependencies required to ensure the presence of
interfaces provided by this library. Any package with binaries
or libraries linking to a shared library must use these files
to determine the required dependencies when it is built. Other
packages which use a shared library (for example using
<tt>dlopen()</tt>) should compute appropriate dependencies
using these files at build time as well.
@@ -5990,21 +5990,25 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)

<p>
The two mechanisms differ in the degree of detail that they
- provide. A <file>symbols</file> file documents for each symbol
- exported by a library the minimal version of the package any
- binary using this symbol will need, which is typically the
- version of the package in which the symbol was introduced.
- This permits detailed analysis of the symbols used by a
+ provide. A <file>symbols</file> file documents, for each symbol
+ exported by a library, the minimal version of the package any
+ binary using this symbol will need. This is typically the
+ version of the package in which the symbol was introduced. This
+ information permits detailed analysis of the symbols used by a
particular package and construction of an accurate dependency,
but it requires the package maintainer to track more information
- about the shared library. A <file>shlibs</file> file, in
- contrast, only documents the last time the library ABI changed
- in any way. It only provides information about the library as a
- whole, not individual symbols. When a package is built using a
- shared library with only a <file>shlibs</file> file, the generated
- dependency will require a version of the shared library equal to
- or newer than the version of the last ABI change. This
- generates unnecessarily restrictive dependencies compared
+ about the shared library.
+ </p>
+
+ <p>
+ A <file>shlibs</file> file, in contrast, only documents the last
+ time the library ABI changed in any way. It only provides
+ information about the library as a whole, not individual
+ symbols. When a package is built using a shared library with
+ only a <file>shlibs</file> file, the generated dependency will
+ require a version of the shared library equal to or newer than
+ the version of the last ABI change. This generates
+ unnecessarily restrictive dependencies compared
to <file>symbols</file> files if none of the symbols used by the
package have changed. This, in turn, may make upgrades
needlessly complex and unnecessarily restrict use of the package
@@ -6012,12 +6016,15 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
</p>

<p>
- <file>shlibs<file> files also have a flawed representation of
+ <file>shlibs<file> files also only support a limited range of
library SONAMEs, making it difficult to use <file>shlibs</file>
files in some unusual corner cases.<footnote>
- libfooN.shlibs says 'libfoo N' instead of the actual SONAME,
- so if the SONAME doesn't match one of the two expected
- formats (libfoo-N.so or libfoo.so.N) it can't be represented.
+ A <file>shlibs</file> file represents an SONAME as a library
+ name and version number, such as <tt>libfoo VERSION</tt>,
+ instead of recording the actual SONAME. If the SONAME doesn't
+ match one of the two expected formats
+ (<tt>libfoo-VERSION.so</tt> or <tt>libfoo.so.VERSION</tt>), it
+ cannot be represented.
</footnote>
</p>

@@ -6029,8 +6036,9 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
maintain. However, maintaining exhaustive symbols information
for a C++ library can be quite onerous, so <file>shlibs</file>
files may be more appropriate for most C++ libraries. Libraries
- with a corresponding udeb must also provide <file>shlibs</file>,
- since the udeb infrastructure does not use <file>symbols</file>.
+ with a corresponding udeb must also provide
+ a <file>shlibs</file> file, since the udeb infrastructure does
+ not use <file>symbols</file> files.
</p>

<sect1 id="dpkg-shlibdeps">
@@ -6089,10 +6097,10 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
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 using the
- <tt>-T</tt> option to the <tt>dpkg</tt> utilities to specify a
- different <file>substvars</file> file for each binary
- package.<footnote>
+ 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
@@ -6166,7 +6174,18 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
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. Adding new symbols to the shared library is a
+ 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

--
Russ Allbery (rra@debian.org) <http://www.eyrie.org/~eagle/>


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 87r4rbu7yg.fsf@windlord.stanford.edu">http://lists.debian.org/87r4rbu7yg.fsf@windlord.stanford.edu
 
Old 08-12-2012, 09:25 PM
Russ Allbery
 
Default Bug#571776: document symbols

Okay, once more for the win. Here is the current version of the patch,
incorporating substantial improvements from Jonathan Nieder and hopefully
incorporating all the feedback in subsequent discussion.

I'm looking for seconds so that we can finally merge this monster.
Presented as a diff since that was the request last time, but the branch
has also been pushed to the Policy Git repository, so if you want to
review it various other ways, you can start at:

http://anonscm.debian.org/gitweb/?p=dbnpolicy/policy.git;a=shortlog;h=refs/heads/bug571776-rra

or with a Policy Git checkout and look at the bug571776-rra branch.

diff --git a/policy.sgml b/policy.sgml
index 8c654d1..fa1c39a 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -889,10 +889,11 @@ zope.
Among those files are the package maintainer scripts
and <file>control</file>, the <qref id="binarycontrolfiles">binary
package control file</qref> that contains the control fields for
- the package. Other control information files
- include <qref id="sharedlibs-shlibdeps">the <file>shlibs</file>
- file</qref> used to store shared library dependency information
- and the <file>conffiles</file> file that lists the package's
+ the package. Other control information files include
+ the <qref id="sharedlibs-symbols"><file>symbols</file> file</qref>
+ or <qref id="sharedlibs-shlibdeps"><file>shlibs</file> file</qref>
+ used to store shared library dependency information and
+ the <file>conffiles</file> file that lists the package's
configuration files (described in <ref id="config-files">).
</p>

@@ -5633,17 +5634,29 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
be placed in a package named
<package><var>libraryname</var><var>soversion</var></package>,
where <var>soversion</var> is the version number in
- the <tt>SONAME</tt> of the shared library.
- See <ref id="shlibs"> for detailed information on how to
- determine this version. Alternatively, if it would be confusing
- to directly append <var>soversion</var>
- to <var>libraryname</var> (if, for example, <var>libraryname</var>
- itself ends in a number), you should use
+ the <tt>SONAME</tt> of the shared library. Alternatively, if it
+ would be confusing to directly append <var>soversion</var>
+ to <var>libraryname</var> (if, for
+ example, <var>libraryname</var> itself ends in a number), you
+ should use
<package><var>libraryname</var>-<var>soversion</var></package>
instead.
</p>

<p>
+ To determine the <var>soversion</var>, look at
+ the <tt>SONAME</tt> of the library, stored in the
+ ELF <tt>SONAME</tt> attribute. it is usually of the
+ form <tt><var>name</var>.so.<var>major-version</var></tt> (for
+ example, <tt>libz.so.1</tt>). The version part is the part
+ which comes after <tt>.so.</tt>, so in that example 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-5.1.so</tt>, in which case the name would
+ be <tt>libdb</tt> and the version would be <tt>5.1</tt>.
+ </p>
+
+ <p>
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 all of their <tt>SONAME</tt>s will
@@ -5678,9 +5691,8 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
linked against the old shared library. Correct versioning of
dependencies on the newer shared library by binaries that use
the new interfaces is handled via
- the <qref id="sharedlibs-shlibdeps"><tt>shlibs</tt>
- system</qref> or via symbols files (see
- <manref name="deb-symbols" section="5">).
+ the <qref id="sharedlibs-depends"><tt>symbols</tt>
+ or <tt>shlibs</tt> system</qref>.
</p>

<p>
@@ -5949,361 +5961,889 @@ Built-Using: grub2 (= 1.99-9), loadlin (= 1.6e-1)
</p>
</sect>

- <sect id="sharedlibs-shlibdeps">
- <heading>Dependencies between the library and other packages -
- the <tt>shlibs</tt> system</heading>
+ <sect id="sharedlibs-depends">
+ <heading>Dependencies between the library and other
+ packages</heading>

<p>
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
- <tt>shlibs</tt> system, which is very simple in its design:
- any package which <em>provides</em> a shared library also
- provides information on the package dependencies required to
- ensure the presence of this library, and any package which
- <em>uses</em> 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 <file>shlibs</file> files.
+ shared library, we must ensure that, when the package is
+ installed on the system, all of the libraries needed are also
+ installed. These dependencies must be added to the binary
+ package when it is built, since they may change based on which
+ version of a shared library the binary or library was linked
+ with even if there are no changes to the source of the binary
+ (for example, symbol versions change, macros become functions or
+ vice versa, or the binary package may determine at compile-time
+ whether new library interfaces are available and can be called).
+ To allow these dependencies to be constructed, shared libraries
+ must provide either a <file>symbols</file> file or
+ a <file>shlibs</file> file. These provide information on the
+ package dependencies required to ensure the presence of
+ interfaces provided by this library. Any package with binaries
+ or libraries linking to a shared library must use these files to
+ determine the required dependencies when it is built. Other
+ packages which use a shared library (for example using
+ <tt>dlopen()</tt>) should compute appropriate dependencies
+ using these files at build time as well.
</p>

<p>
- 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>
+ The two mechanisms differ in the degree of detail that they
+ provide. A <file>symbols</file> file documents, for each symbol
+ exported by a library, the minimal version of the package any
+ binary using this symbol will need. This is typically the
+ version of the package in which the symbol was introduced. This
+ information permits detailed analysis of the symbols used by a
+ particular package and construction of an accurate dependency,
+ but it requires the package maintainer to track more information
+ about the shared library.
+ </p>
+
+ <p>
+ A <file>shlibs</file> file, in contrast, only documents the last
+ time the library ABI changed in any way. It only provides
+ information about the library as a whole, not individual
+ symbols. When a package is built using a shared library with
+ only a <file>shlibs</file> file, the generated dependency will
+ require a version of the shared library equal to or newer than
+ the version of the last ABI change. This generates
+ unnecessarily restrictive dependencies compared
+ to <file>symbols</file> files if none of the symbols used by the
+ package have changed. This, in turn, may make upgrades
+ needlessly complex and unnecessarily restrict use of the package
+ on systems with older versions of the shared libraries.
+ </p>
+
+ <p>
+ <file>shlibs<file> files also only support a limited range of
+ library SONAMEs, making it difficult to use <file>shlibs</file>
+ files in some unusual corner cases.<footnote>
+ A <file>shlibs</file> file represents an SONAME as a library
+ name and version number, such as <tt>libfoo VERSION</tt>,
+ instead of recording the actual SONAME. If the SONAME doesn't
+ match one of the two expected formats
+ (<tt>libfoo-VERSION.so</tt> or <tt>libfoo.so.VERSION</tt>), it
+ cannot be represented.
+ </footnote>
+ </p>
+
+ <p>
+ <file>symbols</file> files are therefore recommended for most
+ shared library packages since they provide more accurate
+ dependencies. For most C libraries, the additional detail
+ required by <file>symbols</file> files is not too difficult to
+ maintain. However, maintaining exhaustive symbols information
+ for a C++ library can be quite onerous, so <file>shlibs</file>
+ files may be more appropriate for most C++ libraries. Libraries
+ with a corresponding udeb must also provide
+ a <file>shlibs</file> file, since the udeb infrastructure does
+ not use <file>symbols</file> files.
+ </p>
+
+ <sect1 id="dpkg-shlibdeps">
+ <heading>Generating dependencies on shared libraries</heading>
+
+ <p>
+ When a package that contains any shared libraries or compiled
+ binaries is built, it must run <prgn>dpkg-shlibdeps</prgn> on
+ each shared library and compiled binary to determine the
+ libraries used and hence the dependencies needed by the
+ package.<footnote>
<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>
+ 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>
- 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 indirectly uses.
- The dependencies for those libraries will automatically pull
- in the other libraries.
- </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>
+ <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>${shlibsepends}</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 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
+ 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 <tt>libdgf</tt> and so they would
- not need rebuilding.
- </p>
- </footnote>
- </p>
-
- <p>
- In the following sections, we will first describe where the
- various <tt>shlibs</tt> files are to be found, then how to
- use <prgn>dpkg-shlibdeps</prgn>, and finally the <tt>shlibs</tt>
- file format and how to create them if your package contains a
- shared library.
- </p>
-
- <sect1>
- <heading>The <tt>shlibs</tt> files present on the system</heading>
-
- <p>
- There are several places where <tt>shlibs</tt> files are
- found. The following list gives them in the order in which
- they are read by
- <qref id="pkg-dpkg-shlibdeps"><prgn>dpkg-shlibdeps</prgn></qref>.
- (The first one which gives the required information is used.)
- </p>
-
- <p>
- <list>
- <item>
- <p><file>debian/shlibs.local</file></p>
-
- <p>
- 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. This file overrides information
- obtained from any other source.
- </p>
- </item>
-
- <item>
- <p><file>/etc/dpkg/shlibs.override</file></p>
-
- <p>
- This lists global overrides. This list is normally
- empty. It is maintained by the local system
- administrator.
- </p>
- </item>
-
- <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
- control information 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
- 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>.
- 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>
-
- <item>
- <p><file>/var/lib/dpkg/info/*.shlibs</file></p>
-
- <p>
- These are the <file>shlibs</file> files corresponding to
- all of the packages installed on the system, and are
- maintained by the relevant package maintainers.
- </p>
- </item>
-
- <item>
- <p><file>/etc/dpkg/shlibs.default</file></p>
-
- <p>
- This file lists any shared libraries whose packages
- have failed to provide correct <file>shlibs</file> files.
- It was used when the <file>shlibs</file> setup was first
- introduced, but it is now normally empty. It is
- maintained by the <tt>dpkg</tt> maintainer.
- </p>
- </item>
- </list>
- </p>
- </sect1>
-
- <sect1>
- <heading>How to use <prgn>dpkg-shlibdeps</prgn> and the
- <file>shlibs</file> files</heading>
-
- <p>
- Put a call to
- <qref id="pkg-dpkg-shlibdeps"><prgn>dpkg-shlibdeps</prgn></qref>
- into your <file>debian/rules</file> file. If your package
- contains only compiled binaries and libraries (but no scripts),
- you can use a command such as:
- <example compact="compact">
-dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/*
- debian/tmp/usr/lib/*
- </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.
- </footnote>
- </p>
-
- <p>
- This command puts the dependency information into the
- <file>debian/substvars</file> file, which is then used by
- <prgn>dpkg-gencontrol</prgn>. You will need to place a
- <tt>${shlibsepends}</tt> variable in the <tt>Depends</tt>
- field in the control file for this to work.
- </p>
-
- <p>
- If you have multiple binary packages, you will need to call
- <prgn>dpkg-shlibdeps</prgn> on each one which contains
- compiled libraries or binaries. In such a case, you will
- need to use the <tt>-T</tt> option to the <tt>dpkg</tt>
- utilities to specify a different <file>substvars</file> file.
- </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>
- For more details on <prgn>dpkg-shlibdeps</prgn>, please see
- <ref id="pkg-dpkg-shlibdeps"> and
- <manref name="dpkg-shlibdeps" section="1">.
- </p>
- </sect1>
-
- <sect1 id="shlibs">
- <heading>The <file>shlibs</file> File Format</heading>
-
- <p>
- Each <file>shlibs</file> file has the same format. Lines
- beginning with <tt>#</tt> are considered to be comments and
- are ignored. Each line is of the form:
- <example compact="compact">
-[<var>type</var>: ]<var>library-name</var> <var>soname-version</var> <var>dependencies ...</var>
- </example>
- </p>
-
- <p>
- We will explain this by reference to the example of the
- <tt>zlib1g</tt> package, which (at the time of writing)
- installs the shared library <file>/usr/lib/libz.so.1.1.3</file>.
- </p>
-
- <p>
- <var>type</var> is an optional element that indicates the type
- of package for which the line is valid. The only type currently
- in use is <tt>udeb</tt>. The colon and space after the type are
- required.
- </p>
-
- <p>
- <var>library-name</var> is the name of the shared library,
- in this case <tt>libz</tt>. (This must match the name part
- of the soname, see below.)
- </p>
-
- <p>
- <var>soname-version</var> 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
- <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">
-objdump -p /usr/lib/libz.so.1.1.3 | grep SONAME
+ 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 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>
- </footnote>
- The version part is the part which comes after
- <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>
- <var>dependencies</var> 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 <ref id="depsyntax"> for details.
- </p>
-
- <p>
- In our example, if the first version of the <tt>zlib1g</tt>
- package which contained a minor number of at least
- <tt>1.3</tt> was <var>1:1.1.3-1</var>, then the
- <tt>shlibs</tt> entry for this library could say:
- <example compact="compact">
-libz 1 zlib1g (>= 1:1.1.3)
- </example>
- The version-specific dependency is to avoid warnings from
- the dynamic linker about using older shared libraries with
- newer binaries.
- </p>
-
- <p>
- As zlib1g also provides a udeb containing the shared library,
- there would also be a second line:
- <example compact="compact">
-udeb: libz 1 zlib1g-udeb (>= 1:1.1.3)
- </example>
- </p>
- </sect1>
-
- <sect1>
- <heading>Providing a <file>shlibs</file> file</heading>
-
- <p>
- If your package provides a shared library, you need to create
- a <file>shlibs</file> file following the format described above.
- It is usual to call this file <file>debian/shlibs</file> (but if
- you have multiple binary packages, you might want to call it
- <file>debian/shlibs.<var>package</var></file> instead). Then
- let <file>debian/rules</file> install it in the control
- information file area:
- <example compact="compact">
-install -m644 debian/shlibs debian/tmp/DEBIAN
- </example>
- or, in the case of a multi-binary package:
- <example compact="compact">
-install -m644 debian/shlibs.<var>package</var> debian/<var>package</var>/DEBIAN/shlibs
- </example>
- An alternative way of doing this is to create the
- <file>shlibs</file> file in the control information file 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 <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>.
- </p>
-
- <p>
- As <prgn>dpkg-shlibdeps</prgn> reads the
- <file>DEBIAN/shlibs</file> files in all of the binary packages
- being built from this source package, all of the
- <file>DEBIAN/shlibs</file> files should be installed before
- <prgn>dpkg-shlibdeps</prgn> is called on any of the binary
- packages.
- </p>
- </sect1>
+ 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>
+ </p>
+
+ <p>
+ Be aware that if a <file>debian/shlibs.local</file> exists
+ in the source package, it will override
+ any <file>symbols</file> files. This is the only case where
+ a <file>shlibs</file> is used despite <file>symbols</file>
+ files being present. See <ref id="shlibs-paths">
+ and <ref id="sharedlibs-shlibdeps"> for more information.
+ </p>
+ </sect2>
+
+ <sect2 id="symbols">
+ <heading>The <file>symbols</file> File Format</heading>
+
+ <p>
+ The following documents the format of
+ the <file>symbols</file> control file as included in binary
+ packages. These files are built from
+ template <file>symbols</file> files in the source package
+ by <prgn>dpkg-gensymbols</prgn>. The template files support
+ a richer syntax that allows <prgn>dpkg-gensymbols</prgn> to
+ do some of the tedious work involved in
+ maintaining <file>symbols</file> files, such as handling C++
+ symbols or optional symbols that may not exist on particular
+ architectures. When writing <file>symbols</file> files for
+ a shared library package, refer
+ to <manref name="dpkg-gensymbols" section="1"> for the
+ richer syntax.
+ </p>
+
+ <p>
+ A <file>symbols</file> may contain one or more entries, one
+ for each shared library contained in the package
+ corresponding to that <file>symbols</file>. Each entry has
+ the following format:
+ </p>
+
+ <p>
+ <example>
+ <var>library-soname</var> <var>main-dependency-template</var>
+ [| <var>alternative-dependency-template</var>]
+ [...]
+ [* <var>field-name</var>: <var>field-value</var>]
+ [...]
+ <var>symbol</var> <var>minimal-version</var>[ <var>id-of-dependency-template</var> ]
+ </example>
+ </p>
+
+ <p>
+ To explain this format, we'll use the the <tt>zlib1g</tt>
+ package as an example, which (at the time of writing)
+ installs the shared
+ library <file>/usr/lib/libz.so.1.2.3.4</file>. Mandatory
+ lines will be described first, followed by optional lines.
+ </p>
+
+ <p>
+ <var>library-soname</var> must contain exactly the value of
+ the ELF <tt>SONAME</tt> attribute of the shared library. In
+ our example, this is <tt>libz.so.1</tt>.<footnote>
+ This can be determined by using the command
+ <example compact="compact">
+ readelf -d /usr/lib/libz.so.1.2.3.4 | grep SONAME
+ </example>
+ </footnote>
+ </p>
+
+ <p>
+ <var>main-dependency-template</var> has the same syntax as a
+ dependency field in a binary package control file, except
+ that the string <tt>#MINVER#</tt> is replaced by a version
+ restriction like <tt>(>= <var>version</var>)</tt> or by
+ nothing if an unversioned dependency is deemed sufficient.
+ The version restriction will be based on which symbols from
+ the shared library are referenced and the version at which
+ they were introduced (see below). In nearly all
+ cases, <var>main-dependency-template</var> will
+ be <tt><var>package</var> #MINVER#</tt>,
+ where <var>package</var> is the name of the binary package
+ containing the shared library. This adds a simple,
+ possibly-versioned dependency on the shared library package.
+ In some rare cases, such as when multiple packages provide
+ the same shared library ABI, the dependency template may
+ need to be more complex.
+ </p>
+
+ <p>
+ In our example, the first line of
+ the <tt>zlib1g</tt> <file>symbols</file> file would be:
+ <example compact="compact">
+ libz.so.1 zlib1g #MINVER#
+ </example>
+ </p>
+
+ <p>
+ Each public symbol exported by the shared library must have
+ a corresponding symbol line, indented by one
+ space. <var>symbol</var> is the exported symbol (which, for
+ C++, means the mangled symbol) followed by <tt>@</tt> and
+ the symbol version, or the string <tt>Base</tt> if there is
+ no symbol version. <var>minimal-version</var> is the most
+ recent version of the shared library that changed the
+ behavior of that symbol, whether by adding it, changing its
+ function signature (the parameters, their types, or the
+ return type), or its behavior in a way that is visible to a
+ caller. <var>id-of-dependency-template</var> is an optional
+ field that references
+ an <var>alternative-dependency-template</var>; see below for
+ a full description.
+ </p>
+
+ <p>
+ For example, <tt>libz.so.1</tt> contains the
+ symbols <tt>compress</tt>
+ and <tt>compressBound</tt>. <tt>compress</tt> has no symbol
+ version and last changed its behavior in upstream
+ version <tt>1:1.1.4</tt>. <tt>compressBound</tt> has the
+ symbol version <tt>ZLIB_1.2.0</tt>, was introduced in
+ upstream version <tt>1:1.2.0</tt>, and has not changed its
+ behavior. Its <file>symbols</file> file therefore contains
+ the lines:
+ <example compact="compact">
+ compress@Base 1:1.1.4
+ compressBound@ZLIB_1.2.0 1:1.2.0
+ </example>
+ Packages using only <tt>compress</tt> would then get a
+ dependency on <tt>zlib1g (>= 1:1.1.4)</tt>, but packages
+ using <tt>compressBound</tt> would get a dependency
+ on <tt>zlib1g (>= 1:1.2.0)</tt>.
+ </p>
+
+ <p>
+ One or more <var>alternative-dependency-template</var> lines
+ may be provided. These are used in cases where some symbols
+ in the shared library should use one dependency template
+ while others should use a different template. The
+ alternative dependency templates are used only if a symbol
+ line contains the <var>id-of-dependency-template</var>
+ field. The first alternative dependency template is
+ numbered 1, the second 2, and so forth.<footnote>
+ An example of where this may be needed is with a library
+ that implements the libGL interface. All GL
+ implementations provide the same set of base interfaces,
+ and then may provide some additional interfaces only used
+ by programs that require that specific GL implementation.
+ So, for example, libgl1-mesa-glx may use the
+ following <file>symbols</file> file:
+ <example>
+ libGL.so.1 libgl1
+ | libgl1-mesa-glx #MINVER#
+ publicGlSymbol@Base 6.3-1
+ [...]
+ implementationSpecificSymbol@Base 6.5.2-7 1
+ [...]
+ </example>
+ Binaries or shared libraries using
+ only <tt>publicGlSymbol</tt> would depend only
+ on <tt>libgl1</tt> (which may be provided by multiple
+ packages), but ones
+ using <tt>implementationSpecificSymbol</tt> would get a
+ dependency on <tt>libgl1-mesa-glx (>= 6.5.2-7)</tt>
+ </footnote>
+ </p>
+
+ <p>
+ Finally, the entry for the library may contain one or more
+ metadata fields. Currently, the only
+ supported <var>field-name</var>
+ is <tt>Build-Depends-Package</tt>, whose value lists
+ the <qref id="sharedlibs-dev">library development
+ package</qref> on which packages using this shared library
+ declare a build dependency. If this field is
+ present, <prgn>dpkg-shlibdeps</prgn> uses it to ensure that
+ the resulting binary package dependency on the shared
+ library is at least as strict as the source package
+ dependency on the shared library development
+ package.<footnote>
+ This field should normally not be necessary, since if the
+ behavior of any symbol has changed, the corresponding
+ symbol <var>minimal-version</var> should have been
+ increased. But including it makes the <tt>symbols</tt>
+ system more robust by tightening the dependency in cases
+ where the package using the shared library specifically
+ requires at least a particular version of the shared
+ library development package for some reason.
+ </footnote>
+ For our example, the <tt>zlib1g</tt> <file>symbols</file>
+ file would contain:
+ <example compact="compact">
+ * Build-Depends-Package: zlib1g-dev
+ </example>
+ </p>
+
+ <p>
+ Also see <manref name="deb-symbols" section="5">.
+ </p>
+ </sect2>
+
+ <sect2 id="providing-symbols">
+ <heading>Providing a <file>symbols</file> file</heading>
+
+ <p>
+ If your package provides a shared library, you should
+ arrange to include a <file>symbols</file> control file
+ following the format described above in that package. You
+ must include either a <file>symbols</file> control file or
+ a <file>shlibs</file> control file.
+ </p>
+
+ <p>
+ Normally, this is done by creating a <file>symbols</file> in
+ the source package
+ named <file>debian/<var>package</var>.symbols</file>
+ or <file>debian/symbols</file>, possibly
+ with <file>.<var>arch</var></file> appended if the symbols
+ information varies by architecture. This file may use the
+ extended syntax documented in <manref name="dpkg-gensymbols"
+ section="1">. Then, call <prgn>dpkg-gensymbols</prgn> as
+ part of the package build process. It will
+ create <file>symbols</file> files in the package staging
+ area based on the binaries and libraries in the package
+ staging area and the <file>symbols</file> files in the
+ source package.<footnote>
+ If you are
+ using <tt>debhelper</tt>, <prgn>dh_makeshlibs</prgn> will
+ take care of calling either <prgn>dpkg-gensymbols</prgn>
+ or generating a <file>shlibs</file> file as appropriate.
+ </footnote>
+ </p>
+
+ <p>
+ Packages that provide <file>symbols</file> files must keep
+ them up-to-date to ensure correct dependencies in packages
+ that use the shared libraries. This means updating
+ the <file>symbols</file> file whenever a new public symbol
+ is added, changing the <var>minimal-version</var> field
+ whenever a symbol changes behavior or signature in a
+ backward-compatible way (see <ref id="sharedlibs-updates">),
+ and changing the <var>library-soname</var>
+ and <var>main-dependency-template</var>, and probably all of
+ the <var>minimal-version</var> fields, when the library
+ changes <tt>SONAME</tt>. Removing a public symbol from
+ the <file>symbols</file> file because it's no longer
+ provided by the library normally requires changing
+ the <tt>SONAME</tt> of the library.
+ See <ref id="sharedlibs-runtime"> for more information
+ on <tt>SONAME</tt>s.
+ </p>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sharedlibs-shlibdeps">
+ <heading>The <tt>shlibs</tt> system</heading>
+
+ <p>
+ The <tt>shlibs</tt> system is an simpler alternative to
+ the <tt>symbols</tt> system for declaring dependencies for
+ shared libraries. It may be more appropriate for C++
+ libraries and other cases where tracking individual symbols is
+ too difficult. It predated the <tt>symbols</tt> system and is
+ therefore frequently seen in older packages. It is also
+ required for udebs, which do not support <tt>symbols</tt>.
+ </p>
+
+ <p>
+ In the following sections, we will first describe where the
+ various <file>shlibs</file> files are to be found, then how to
+ use <prgn>dpkg-shlibdeps</prgn>, and finally
+ the <file>shlibs</file> file format and how to create them.
+ </p>
+
+ <sect2 id="shlibs-paths">
+ <heading>The <file>shlibs</file> files present on the
+ system</heading>
+
+ <p>
+ There are several places where <tt>shlibs</tt> files are
+ found. The following list gives them in the order in which
+ they are read by <prgn>dpkg-shlibdeps</prgn>. (The first
+ one which gives the required information is used.)
+ <list>
+ <item>
+ <p><file>debian/shlibs.local</file></p>
+
+ <p>
+ 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. This file overrides information
+ obtained from any other source.
+ </p>
+ </item>
+
+ <item>
+ <p><file>/etc/dpkg/shlibs.override</file></p>
+
+ <p>
+ This lists global overrides. This list is normally
+ empty. It is maintained by the local system
+ administrator.
+ </p>
+ </item>
+
+ <item>
+ <p><file>DEBIAN/shlibs</file> files in the "build
+ directory"</p>
+
+ <p>
+ These files are generated as part of the package build
+ process and staged for inclusion as control files in
+ the binary packages being built. They provide details
+ of any shared libraries included in the same package.
+ </p>
+ </item>
+
+ <item>
+ <p><file>shlibs</file> control files for packages
+ installed on the system</p>
+
+ <p>
+ The <file>shlibs</file> control files for all the
+ packages currently installed on the system. 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>
+ shlibs</tt> if for some reason these files need to be
+ examined.
+ </p>
+ </item>
+
+ <item>
+ <p><file>/etc/dpkg/shlibs.default</file></p>
+
+ <p>
+ This file lists any shared libraries whose packages
+ have failed to provide correct <file>shlibs</file>
+ files. It was used when the <file>shlibs</file> setup
+ was first introduced, but it is now normally empty.
+ It is maintained by the <tt>dpkg</tt> maintainer.
+ </p>
+ </item>
+ </list>
+ </p>
+
+ <p>
+ If a <file>symbols</file> file for a shared library package
+ is available, <prgn>dpkg-shlibdeps</prgn> will always use it
+ in preference to a <file>shlibs</file>, with the exception
+ of <file>debian/shlibs.local</file>. The latter overrides
+ any other <file>shlibs</file> or <file>symbols</file> files.
+ </p>
+ </sect2>
+
+ <sect2 id="shlibs">
+ <heading>The <file>shlibs</file> File Format</heading>
+
+ <p>
+ Each <file>shlibs</file> file has the same format. Lines
+ beginning with <tt>#</tt> are considered to be comments and
+ are ignored. Each line is of the form:
+ <example compact="compact">
+ [<var>type</var>: ]<var>library-name</var> <var>soname-version</var> <var>dependencies ...</var>
+ </example>
+ </p>
+
+ <p>
+ We will explain this by reference to the example of the
+ <tt>zlib1g</tt> package, which (at the time of writing)
+ installs the shared
+ library <file>/usr/lib/libz.so.1.2.3.4</file>.
+ </p>
+
+ <p>
+ <var>type</var> is an optional element that indicates the
+ type of package for which the line is valid. The only type
+ currently in use is <tt>udeb</tt>. The colon and space
+ after the type are required.
+ </p>
+
+ <p>
+ <var>library-name</var> is the name of the shared library,
+ in this case <tt>libz</tt>. (This must match the name part
+ of the soname, see below.)
+ </p>
+
+ <p>
+ <var>soname-version</var> is the version part of the
+ ELF <tt>SONAME</tt> attribute of the library, determined the
+ same way that the <var>soversion</var> component of the
+ recommended shared library package name is determined.
+ See <ref id="sharedlibs-runtime"> for the details.
+ </p>
+
+ <p>
+ <var>dependencies</var> 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 <ref id="depsyntax"> for details on the
+ syntax, and <ref id="sharedlibs-updates"> for details on how
+ to maintain the dependency version constraint.
+ </p>
+
+ <p>
+ In our example, if the last change to the <tt>zlib1g</tt>
+ package that could change behavior for a client of that
+ library was in version <tt>1:1.2.3.3.dfsg-1</tt>, then
+ the <tt>shlibs</tt> entry for this library could say:
+ <example compact="compact">
+ libz 1 zlib1g (>= 1:1.2.3.3.dfsg-1)
+ </example>
+ This version restriction must be new enough that any binary
+ built against the current version of the library will work
+ with any version of the shared library that satisfies that
+ dependency.
+ </p>
+
+ <p>
+ As zlib1g also provides a udeb containing the shared
+ library, there would also be a second line:
+ <example compact="compact">
+ udeb: libz 1 zlib1g-udeb (>= 1:1.2.3.3.dfsg-1)
+ </example>
+ </p>
+ </sect2>
+
+ <sect2>
+ <heading>Providing a <file>shlibs</file> file</heading>
+
+ <p>
+ To provide a <file>shlibs</file> file for a shared library
+ binary package, create a <file>shlibs</file> file following
+ the format described above and place it in
+ the <file>DEBIAN</file> directory for that package during
+ the build. It will then be included as a control file for
+ that package<footnote>
+ 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>.
+ </p>
+
+ <p>
+ Since <prgn>dpkg-shlibdeps</prgn> reads
+ the <file>DEBIAN/shlibs</file> files in all of the binary
+ packages being built from this source package, all of
+ the <file>DEBIAN/shlibs</file> files should be installed
+ before <prgn>dpkg-shlibdeps</prgn> is called on any of the
+ binary packages.
+ </p>
+ </sect2>
+ </sect1>
</sect>
</chapt>

@@ -7900,8 +8440,9 @@ INSTALL = install -s # (or use strip on the files in debian/tmp)
Although not enforced by the build tools, shared libraries
must be linked against all libraries that they use symbols from
in the same way that binaries are. This ensures the correct
- functioning of the <qref id="sharedlibs-shlibdeps">shlibs</qref>
- system and guarantees that all libraries can be safely opened
+ functioning of the <qref id="sharedlibs-symbols">symbols</qref>
+ and <qref id="sharedlibs-shlibdeps">shlibs</qref>
+ systems and guarantees that all libraries can be safely opened
with <tt>dlopen()</tt>. Packagers may wish to use the gcc
option <tt>-Wl,-z,defs</tt> when building a shared library.
Since this option enforces symbol resolution at build time,
@@ -10713,82 +11254,10 @@ END-INFO-DIR-ENTRY
</heading>

<p>
- This program is usually called from <file>debian/rules</file>
- just before <prgn>dpkg-gencontrol</prgn> (see <ref
- id="pkg-sourcetree">), in the top level of the source tree.
- </p>
-
- <p>
- Its arguments are executables and shared libraries
- <footnote>
- <p>
- They may be specified either in the locations in the
- source tree where they are created or in the locations
- in the temporary build tree where they are installed
- prior to binary package creation.
- </p>
- </footnote> for which shared library dependencies should
- be included in the binary package's control file.
- </p>
-
- <p>
- If some of the found shared libraries should only
- warrant a <tt>Recommends</tt> or <tt>Suggests</tt>, or if
- some warrant a <tt>Pre-Depends</tt>, this can be achieved
- by using the <tt>-d<var>dependency-field</var></tt> option
- before those executable(s). (Each <tt>-d</tt> option
- takes effect until the next <tt>-d</tt>.)
- </p>
-
- <p>
- <prgn>dpkg-shlibdeps</prgn> does not directly cause the
- output control file to be modified. Instead by default it
- adds to the <file>debian/substvars</file> file variable
- settings like <tt>shlibsepends</tt>. These variable
- settings must be referenced in dependency fields in the
- appropriate per-binary-package sections of the source
- control file.
- </p>
-
- <p>
- For example, a package that generates an essential part
- which requires dependencies, and optional parts that
- which only require a recommendation, would separate those
- two sets of dependencies into two different fields.<footnote>
- At the time of writing, an example for this was the
- <package/xmms/ package, with Depends used for the xmms
- executable, Recommends for the plug-ins and Suggests for
- even more optional features provided by unzip.
- </footnote>
- It can say in its <file>debian/rules</file>:
- <example>
- dpkg-shlibdeps -dDepends <var>program anotherprogram ...</var>
- -dRecommends <var>optionalpart anotheroptionalpart</var>
- </example>
- and then in its main control file <file>debian/control</file>:
- <example>
- <var>...</var>
- Depends: ${shlibsepends}
- Recommends: ${shlibs:Recommends}
- <var>...</var>
- </example>
- </p>
-
- <p>
- Sources which produce several binary packages with
- different shared library dependency requirements can use
- the <tt>-p<var>varnameprefix</var></tt> option to override
- the default <tt>shlibs:</tt> prefix (one invocation of
- <prgn>dpkg-shlibdeps</prgn> per setting of this option).
- They can thus produce several sets of dependency
- variables, each of the form
- <tt><var>varnameprefix</var>:<var>dependencyfield</var></tt>,
- which can be referred to in the appropriate parts of the
- binary package control files.
+ See <manref name="dpkg-shlibdeps" section="1">.
</p>
</sect1>

-
<sect1 id="pkg-dpkg-distaddfile">
<heading>
<prgn>dpkg-distaddfile</prgn> - adds a file to

--
Russ Allbery (rra@debian.org) <http://www.eyrie.org/~eagle/>


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: 87lihju7k7.fsf@windlord.stanford.edu">http://lists.debian.org/87lihju7k7.fsf@windlord.stanford.edu
 

Thread Tools




All times are GMT. The time now is 03:41 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org