Russ Allbery <r...@debian.org> writes:

> I read through the shared library sections of Policy a few times last
> night and can't find anywhere where Policy unambiguously recommends
> always including a version in SONAME for public libraries.  If you don't
> have a version, you can't represent the library in the shlibs format, so
> there's an implicit recommendation, but I think it would be better to
> make it explicit.

There was a lot of background information missing from Policy, which in my
opinion made it unnecessarily difficult to understand the motivation and
implications of the various Policy requirements.  Here's a first draft of
a patch to add much more information about how shared libraries work,
better motivate the requirements already present (and tighten some of the
language), and add a should-level requirement to change the SONAME if the
library ABI changes.

Objections, sections, or other review?

diff --git a/policy.sgml b/policy.sgml
index 7736ddb..2d535d3 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -5106,55 +5106,138 @@ Replaces: mail-transport-agent
       </p>
 
       <p>
-       Packages involving shared libraries should be split up into
-       several binary packages. This section mostly deals with how
-       this separation is to be accomplished; rules for files within
-       the shared library packages are in <ref id="libraries"> instead.
+       This section deals only with public shared libraries: shared
+       libraries that are placed in directories searched by the dynamic
+       linker by default or which are intended to be linked against
+       normally and possibly used by other, independent packages.  Shared
+       libraries that are internal to a particular package or that are
+       only loaded as dynamic modules are not covered by this section and
+       are not subject to its requirements.
       </p>
 
-      <sect id="sharedlibs-runtime">
-       <heading>Run-time shared libraries</heading>
+      <p>
+       A shared library must be uniquely identified by an <tt>SONAME</tt>
+       attribute stored in its dynamic section.  When a binary is linked
+       against a shared library, the <tt>SONAME</tt> of the shared
+       library is recorded in the binary's <tt>NEEDED</tt> section so
+       that the dynamic linker knows that library must be loaded at
+       runtime.  The full name of the shared library (which usually
+       contains additional version information not needed in
+       the <tt>SONAME</tt> is therefore not referenced directly.
+       Instead, the shared library is loaded by its <tt>SONAME</tt>,
+       which exists on the file system as a symlink pointing to the full
+       name of the shared library.<footnote>
+         Some unusual libraries have an <tt>SONAME</tt> which matches the
+         full library name, but normally there is a minor revision that
+         changes even though the ABI has not changed in a
+         backward-incompatible way.  The <tt>SONAME</tt> only changes
+         when binaries linked with the earlier version of the shared
+         library may no longer work.  See <ref id="sharedlibs-runtime">
+         for more information.
+       </footnote>
+       This symlink is updated and its location cached
+       by <prgn>ldconfig</prgn>, but must also be created by the
+       package.  <ref id="sharedlibs-runtime"> describes how to do this.
+      </p>
 
       <p>
-       The run-time shared library needs to be placed in a package
-        whose name changes whenever the shared object version
-        changes.<footnote>
-            <p>
-              Since it is common place to install several versions of a
-              package that just provides shared libraries, it is a
-              good idea that the library package should not
-              contain any extraneous non-versioned files, unless they
-              happen to be in versioned directories.</p>
-          </footnote>
-          The most common mechanism is to place it in a package
-        called
-        <package><var>libraryname</var><var>soversion</var></package>,
-        where <file><var>soversion</var></file> is the version number
-        in the soname of the shared library<footnote>
-             The soname is the shared object name: it's the thing
-             that has to match exactly between building an executable
-             and running it for the dynamic linker to be able run the
-             program.  For example, if the soname of the library is
-             <file>libfoo.so.6</file>, the library package would be
-             called <file>libfoo6</file>.
-         </footnote>.
-       Alternatively, if it would be confusing to directly append
-       <var>soversion</var> to <var>libraryname</var> (e.g. because
-       <var>libraryname</var> itself ends in a number), you may use
-       <package><var>libraryname</var>-<var>soversion</var></package> and
-       <package><var>libraryname</var>-<var>soversion</var>-dev</package>
-       instead.
+       When linking a binary or another shared library against a shared
+       library, the <tt>SONAME</tt> for that shared library is not yet
+       known.  Instead, the shared library is found by library name
+       with <tt>.so</tt> appended.  This file exists on the file system
+       as a symlink pointing to the shared library.<footnote>
+         Some shared libraries have no version information in
+         their <tt>SONAME</tt> and therefore need no symlink since the
+         file found when linking is the same as the library name.  This
+         is highly unusual, however, and means the shared library cannot
+         be versioned.  It is used only for very special situations where
+         the shared library provides a tiny set of symbols and must not
+         be versioned for some reason.
+       </footnote>
+      </p>
+
+      <p>
+       Shared libraries are normally split into several binary packages.
+       The <tt>SONAME</tt> symlink is installed by the runtime shared
+       library package, and the bare <tt>.so</tt> symlink is installed in
+       the development package since it's only used when linking binaries
+       or shared libraries.  However, there are some exceptions for
+       unusual shared libraries or for shared libraries that are also
+       loaded as dynamic modules by other programs.
       </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 you change all of
-       their sonames at once (so that you don't get filename
-       clashes if you try to install different versions of the
-       combined shared libraries package).
+       This section is primarily concerned with how the separation of
+       shared libraries into multiple packages should be done and how
+       dependencies on and between shared library binary packages are
+       managed in Debian.  <ref id="libraries"> should be read in
+       conjunction with this section and contains additional rules for
+       the files contained in the shared library packages.
       </p>
 
+      <sect id="sharedlibs-runtime">
+       <heading>Run-time shared libraries</heading>
+
+       <p>
+         The run-time shared library must be placed in a package
+         whose name changes whenever the <tt>SONAME</tt> of the shared
+         library changes.  This allows several versions of the shared
+         library to be installed at the same time, allowing installation
+         of the new version of the shared library without immediately
+         breaking binaries that depend on the old version.  Normally, the
+         run-time shared library and its <tt>SONAME</tt> symlink should
+         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
+         <package><var>libraryname</var>-<var>soversion</var></package>
+         instead.
+       </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
+         always change together.  Be aware that this is not normally the
+         case, and if the <tt>SONAME</tt>s do not change together,
+         upgrading such a merged shared library package will be
+         unnecessarily difficult because of file conflicts with the old
+         version of the package.  When in doubt, always split shared
+         library packages so that each binary package installs a single
+         shared library.
+       </p>
+
+       <p>
+         Every time the shared library ABI changes in a way that may
+         break binaries linked against older versions of the shared
+         library, the <tt>SONAME</tt> of the library and the
+         corresponding name for the binary package containing the runtime
+         shared library should change.  Normally, this means
+         the <tt>SONAME</tt> must 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.
+       </p>
+
+       <p>
+         The <tt>SONAME</tt> and binary package name need not, and indeed
+         normally should not, change if new interfaces are added but none
+         are removed or changed, since this will not break binaries
+         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>shilbs</tt>
+         system</qref>.
+       </p>
+
       <p>
        The package should install the shared libraries under
        their normal names.  For example, the <package>libgdbm3</package>
@@ -5174,10 +5257,11 @@ Replaces: mail-transport-agent
       </p>
 
       <p>
-       The run-time library package should include the symbolic link that
-       <prgn>ldconfig</prgn> would create for the shared libraries.
-       For example, the <package>libgdbm3</package> package should include
-       a symbolic link from <file>/usr/lib/libgdbm.so.3</file> to
+       The run-time library package should include the symbolic link for
+       the <tt>SONAME</tt> that <prgn>ldconfig</prgn> would create for
+       the shared libraries.  For example,
+       the <package>libgdbm3</package> package should include a symbolic
+       link from <file>/usr/lib/libgdbm.so.3</file> to
        <file>libgdbm.so.3.0.0</file>.  This is needed so that the dynamic
        linker (for example <prgn>ld.so</prgn> or
        <prgn>ld-linux.so.*</prgn>) can find the library between the


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



-- 
To UNSUBSCRIBE, email to debian-policy-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/878w5lc31g....@windlord.stanford.edu

Reply via email to