"Didier 'OdyX' Raboud" <email@example.com> writes:
> f) that the vast majority of library depencies are handled with ">="
> dependencies despite no technical guarantees of ABI stability (besides
> Debian-specific symbol tracking);
While there are no *technical* guarantees, there is the expectation that
anyone maintaining a shared library will increase the SONAME when there is
any non-backward-compatible change to a public symbol. Not doing this is
a Policy violation, and is usually release-critical (although this can
depend on the situation).
Unsupported internal APIs are one of the possible exceptions. We just
rewrote this section in the most recent Policy update to try to make it
Every time the shared library ABI changes in a way that may break
binaries linked against older versions of the shared library, the
SONAME of the library and the corresponding name for the binary
package containing the runtime shared library should change.
Normally, this means the SONAME should change any time an interface is
removed from the shared library or the signature of an interface (the
number of parameters or the types of parameters that it takes, for
example) is changed. This practice is vital to allowing clean
upgrades from older versions of the package and clean transitions
between the old ABI and new ABI without having to upgrade every
affected package simultaneously.
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. 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.
 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 Breaks 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.
In practice, divergence from the upstream SONAME practice is probably a
bad idea. This business of having an exposed private API is dangerous and
constitutes bad API design on upstream's part, but that's not something
that we can easily fix in Debian, and diverging too far from upstream is
probably counter-productive. Therefore, I think using a tight (=)
dependency for consumers of the private API is a reasonable compromise
given the situation as I understand it.
I do recommend doing something that will happen automatically without the
packager having to think about it if this is a common occurance (not, for
example, a one-time change to the private interface that only happens
every five years or so), such as a hardcoded = dependency in
> g) that, to my knowledge, too-tight dependencies hurt upgrade paths;
Insufficiently tight dependencies to guarantee that software continues to
work properly hurts upgrade paths even more. :) We should not be
reluctant to use our dependency system accurately and expect the
dependency resolvers to work properly.
Russ Allbery (firstname.lastname@example.org) <http://www.eyrie.org/~eagle/>