<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "/usr/share/sgml/docbook/dtd/xml/4.2/docbookx.dtd">
<!-- 
  Currently the original is in http://www.netfort.gr.jp/~dancer/column/libpkg-guide
  -->
<book id="book" lang="en">
  <title>Debian Library Packaging Guide</title>
  <titleabbrev>libpkg-guide</titleabbrev>
  <bookinfo>
    <title>Debian Library Packaging guide</title>
    <copyright>
      <year>2002-2006</year>
      <holder>Junichi Uekawa</holder>
    </copyright>
    <legalnotice>
      <para>
	Distributed under the terms and conditions of GPL version 2 or
	later. 
      </para>
    </legalnotice>
  </bookinfo>
  <chapter id="introduction">
    <title>Introduction</title>
    <para>
      This guide tries to illustrate and illuminate the problems 
      related to library packaging to be clear to the Developers
      of Debian Project,
      to hopefully raise the general awareness, and to fill the gap of
      Debian documentation lacking in the direction of library package.
    </para>
    <para>
      Hopefully this document will improve and become more accurate as
      criticisms come.  The document will hopefully improve the
      general quality of Debian, and provide a good reading for Debian
      developers, instead of the "don't even dare packaging libraries
      if you are a newbie" policy, which used to be the air in
      debian-devel mailing list before this document was born back in
      2002.
    </para>
    <para>
      Latest version of this document is currently available at
      <ulink url="http://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.html">
	http://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.html
      </ulink>
      <ulink url="http://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.pdf">
	(PDF version)
      </ulink>
      <ulink url="http://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.xml">
	(XML source)
      </ulink>
    </para>
  </chapter>
  <chapter id="debiantrait">
    <title>Traits of Debian</title>
    <para>
      First, let us check what Debian is from the perspective of 
      maintaining library packages, and why Debian is different to 
      other systems.
    </para>
    <para>Debian is a binary-distribution-oriented system.
      The binaries are created from source packages and are the ones that
      get distributed.
      The binaries are from the source as a snapshot for one architecture
      and several copies of the binaries are built from the same source at
      different times for different architectures, sometimes even against 
      different versions of libraries.
    </para>
    <para>
      Thus, unless one is careful, one has no control over which version of 
      specific development package a binary will be compiled with.
    </para>
    <para>
      The SONAME of a library will help, as we will see in a moment.
    </para>
    <para>From the point of a single distribution all packages should
      use the same version to reduce the number of installed packages and
      increase the possibility of sharing loaded libraries.
      And from the viewpoint of a distribution which can be upgraded,
      several different incompatible 
      versions of shared libraries should be able to coexist.
    </para>
    <para>
      Debian has a packaging scheme for libraries, with having
      libfooX package for run-time required library files,
      and libfooX-dev package for build-time required library files.
    </para>
    <para>
      Other systems have a different approach to the problem.
      Some systems try to rebuild the whole system in one 
      run, compiling against one version of single shared library.
      This is an ideal way, but requires a lot of resource to 
      rebuild all packages in the archive. 
    </para>
    <para>
      Some other systems (including the ones which call their
      shared libraries .DLL) don't allow for upgrades, and assume that
      libraries are never upgraded, and even if they are upgraded
      they will be always compatible. Such systems are susceptible
      to random, very difficult to track, errors.
    </para>
  </chapter>
  <chapter id="recommendedreading">
    <title>Recommended reading before doing library packages</title>

    <para>
      For detailed information on libraries, it is recommended to read
      the info page for libtool, which is contained in the libtool-doc
      package.  It explains many things in detail, and talks about
      generic aspects of library programs not specific to Debian.
      Reading <command>ld</command> documentation in binutils-doc
      package is also interesting.
    </para>
    <para>
      For Debian packaging backgrounds, please read the respective
      documentation for Debian Developers.  Namely the Debian Policy,
      the New Maintainers' Guide, and the Developer's Reference.  (An
      experience of having your package broken by some random library
      upgrade might be a plus, but hopefully this document will give
      you an idea of what kind of disaster happens when shared
      libraries break.)
    </para>
  </chapter>

  <chapter id="shldevpackagecontents">
    <title>Contents of the shared library package and development package</title>
    <para>
      In this chapter, what files are contained in which package is explained.
    </para>
    <section>
      <title>Files in lib* package</title>
      <para>
	In the lib* (e.g. in this text, libfooX is used as an example,
	foo being the name of the package and X being a numeric
	number.) package, only the runtime library, and the files
	necessary to use the runtime library should be included in
	such a way that different versions of the runtime library can
	be co-installed on a user's system.
      </para>
      <para>
	Usually, it contains the library file itself, 
	somehow called <filename>libfoo.so.X.X.X</filename>
	and its symlink <filename>libfoo.so.X</filename>
	which matches the SONAME.
	<footnote>
	  <para> The SONAME may or may not end in a numerical value
	    depending on the linkage option, and it is usually
	    necessary to use <command>objdump</command> to really
	    check it out.
	  </para>
	</footnote>
      </para>
      <para>
	When plugins and runtime binaries exist that are essential 
	for using the shared library at runtime,
	they should be placed under a directory that can be 
	derived uniquely from the SONAME.
	Usually that means they should reside under
	<filename>/usr/lib/libfooX/</filename>
	where libfooX is the full package name for
	the library package.
      </para>
    </section>
    <section>
      <title>-DEV package</title>
      <para>
	-DEV package (e.g. libfooX-dev) should contain the 
	development symlink used when linking,
	static libraries, and header files,
	and if they exist, package configuration scripts.
	<table>
	  <title>Annotated list of files that usually reside in -DEV package</title>
	  <tgroup cols="2">
	    <colspec colnum="1" colname="c1" colwidth="1*" align="left" />
	    <colspec colnum="2" colname="c2" colwidth="2*" align="left" />
	    <thead>
	      <row>
		<entry>files</entry>
		<entry>meaning</entry>
	      </row>
	    </thead>
	    <tbody>
	      <row>
		<entry>usr/lib/*.so</entry>
		<entry>development linkage file, used when other programs are
		linked with -lxxx</entry>
	      </row>
	      <row>
		<entry>usr/lib/*.a</entry>
		<entry>static link files</entry>
	      </row>
	      <row>
		<entry>usr/lib/*.la</entry>
		<entry>libtool linkage information file</entry>
	      </row>
	      <row>
		<entry>usr/include/*</entry>
		<entry>Development include files</entry>
	      </row>
	      <row>
		<entry>usr/bin/*-config</entry>
		<entry>Some configuration script used in obtaining the library paths, like <filename>gtk-config</filename></entry>
	      </row>
	      <row>
		<entry>usr/lib/pkgconfig/*.pc</entry>
		<entry>Some information required for <command>pkgconfig</command></entry>
	      </row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
    </section>
    <section>
      <title>Other files, plugins, runtime binaries</title>
      <para>
	Usually upstream shared library packages contain some
	documentation and example runtime binaries.
	They should not reside in the runtime shared library package.
	They should be put in the -DEV package, or 
	another package that does not have a SONAME version number appended
	on it, such as <filename>libfoo-runtime</filename>
      </para>
      <para>
	This is because the ability of runtime shared library package
	to upgrade and coexist suffers if the binaries are included in
	the runtime shared library package.
      </para>
      <para>
	There are plugin files, and binaries that are required by the 
	shared library at run-time, which cannot be split out from
	the shared library.
	They are placed under a versioned directory inside <filename>/usr/lib</filename>.
	Examples include <filename>/usr/lib/pango/1.0.0/modules/pango-arabic-ft2.so</filename>
	for pango-1.0-0 modules, <filename>/usr/lib/vdkbuilder2/libvdkbcalendar.so.2</filename>
	for vdkbuilder2 modules, etc.
      </para>
      <para>
	<filename>/libexec</filename> directory in GNU Coding Standards was
	designed to allow versioned binaries to exist. However, use of 
	<filename>libexec</filename> is not currently allowed under current Debian policy.
	Use subdirectories of <filename>/usr/lib/libfooX</filename>.
      </para>
    </section>
    <section>
      <title>Example of which packages the files belong to when using libtool</title>
      <para>
	It is not immediately clear which files go to where when using 
	libtool. The following table shows a list.
      </para>
      <table>
	<title>The relationship between the link-time libtool command-line option and 
	the actual file contents of each package</title>
	<tgroup cols="5">
	  <colspec colnum="1" colname="c1" colwidth="1*" align="left" />
	  <colspec colnum="2" colname="c2" colwidth="1*" align="left" />
	  <colspec colnum="3" colname="c3" colwidth="1*" align="left" />
	  <colspec colnum="4" colname="c4" colwidth="1*" align="left" />
	  <colspec colnum="5" colname="c5" colwidth="1*" align="left" />

	  <thead>
	    <row>
	      <entry>The libtool command-line</entry>
	      <entry>libfoo package name</entry>
	      <entry>libfoo package contents</entry>
	      <entry>libfoo-dev package name</entry>
	      <entry>libfoo-dev package contents</entry>
	    </row>
	  </thead>
	  <tbody>
	    <row>
	      <entry>-export-dynamic -version-info 0:0:0 -release 1.2.3</entry>
	      <entry>libfoo-1.2.3-0</entry>
	      <entry>libfoo-1.2.3.so.0, libfoo-1.2.3.so.0.0.0 </entry>
	      <entry>libfoo-1.2.3-0-dev</entry>
	      <entry>libfoo.so, libfoo.a, libfoo.la	 </entry>
	    </row>
	    <row>
	      <entry>-export-dynamic -release 1.2.3</entry>
	      <entry>libfoo-1.2.3</entry>
	      <entry>libfoo-1.2.3.so</entry>
	      <entry>libfoo-1.2.3-dev</entry>
	      <entry>libfoo.so, libfoo.a, libfoo.la	 </entry>
	    </row>
	    <row>
	      <entry>-export-dynamic -version-info 0:0:0</entry>
	      <entry>libfoo0</entry>
	      <entry>libfoo.so.0, libfoo.so.0.0.0 </entry>
	      <entry>libfoo0-dev</entry>
	      <entry>libfoo.so, libfoo.a, libfoo.la	 </entry>
	    </row>
	  </tbody>
	</tgroup>
      </table>
    </section>
  </chapter>

  <chapter id="shlibpkgs">
    <title>shared library packages</title>
    <section id="sonameapiabi">
      <title>SONAMEs, API and ABI</title>
      <para>
	In most cases, if a package version matches the SONAME,
	it is a sign that there is a problem with the versioning 
	scheme. Scrap it, and bash the upstream with the libtool manual.
	It is usually a good sign that either he has not read the manual
	thoroughly, or he has not understood it, or both.
      </para>
      <para>
	A SONAME is an information stored in a shared library,
	which can be seen with the command
	<command>objdump -p <parameter>filename</parameter> | grep SONAME</command>. 
	The value is referenced from binaries and shared libraries 
	when linking, and embedded in the NEEDED fields, which can
	be seen with <command>objdump -p <parameter>filename</parameter> | grep NEEDED</command>. 
	A soname usually looks something like <filename>libfoo.so.0</filename>.
      </para>
      <para>
	If a package keeps the same SONAME, it should mean that
	the <emphasis>BINARY COMPATIBILITY IS KEPT</emphasis>
	(however, it's not always the case).
      </para>
      <para> 
	If a new version of a library package breaks a currently
	existing and working package (the ABI), the SONAME version
	number should be bumped up, or the change be reverted, or
	both.  By bumping up the SONAME version number, the old
	binaries which used to link to the old version of the library
	should be able to run with the old library, and the new and
	the old libraries can coexist.
      </para>
      <para> 
	Signs of binary incompatibility include: function
	declaration change, change of "struct" contents, and changing
	semantics of functions (hard to detect).
      </para>
      <para>
	If it only requires a source rebuild, it is called a ABI
	breakage.  When even a rebuild is not enough, and there is a
	source-level change required for applications to work with the
	new version of the library, it is called a API breakage, and a
	different -DEV package name should be chosen for the new
	version of the shared library package.
      </para>
    </section>
    <section>
      <title>Choosing which method to use for versioning</title>
      <para>
	The upstream authors have the liberty of choosing 
	two major methods for versioning using libtool.
	-version-info, and -release.
	-release is used for unstable libraries that change ABI 
	on every new release.
	However, such unstable library package usually don't belong 
	in Debian, because it will require a rebuild in every dependent 
	package against the new library package.
      </para>
      <para>
	-release is recently used more for signifying major releases.
	Due to the serial nature of -version-info, SONAME version numbers
	usually get quite large fairly quickly. Using new -release
	value in major library release, the SONAME version numbers can be 
	re-set to zero. 
	Some people prefer the lower numbers.
      </para>
    </section>
    <section id="naminglibpkg">
      <title>Naming shared library packages</title>
      <para>
	The policy documents how to name library packages.
	<filename>"lib[libraryname][SONAME-version-number]"</filename>
	like 
	<filename>"libc6"</filename>
	for <filename>/lib/libc.so.6</filename>
      </para>
      <para>	
	However, there are packages which contain libraries that look like this:
      </para>
      <screen>	
	/usr/lib/libfoo-1.2.so.0
      </screen>	 
      <para>	
	This is a library with a name of <filename>libfoo-1.2</filename>, and a SONAME version number of "0".
	The current practice in packaging such package is to have 
	<filename>libfoo-1.2-0</filename>
	or
	<filename>libfoo1.2-0</filename>
	as the package name, and the recommended practice is to have 
	<filename>libfoo-1.2-0</filename>
      </para>
      <para>	
	Do not make it <filename>libfoo1.20</filename>, since it is ambiguous.
      </para>
      <para>
	The package name should match the shared library SONAME.
	It can be deduced with <command>sed s/\.so\./-/</command>
	and removing <quote>-</quote> later 
	when removing it will not result in consecutive numbers.
	Or by using the following code snippet from Steve Langasek.
      </para>
      <para>
	<screen>
$ objdump -p /path/to/libfoo-bar.so.1.2.3 | \
  sed -n -e's/^[[:space:]]*SONAME[[:space:]]*//p' | \
  sed -e's/\([0-9]\)\.so\./\1-/; s/\.so\.//'
	</screen>
      </para>
      <para>
	<table>
	  <title>Example match between SONAME and package name </title>
	  <tgroup cols="2">
	    <thead>
	      <row>
		<entry>SONAME</entry>
		<entry>package name</entry>
	      </row>
	    </thead>
	    <tbody>
	      <row>
		<entry>libfoo-1.2.3.so.4</entry>
		<entry>libfoo-1.2.3-4</entry>
	      </row>
	      <row>
		<entry>libfoo-1.2.3.so</entry>
		<entry>libfoo-1.2.3</entry>
	      </row>
	      <row>
		<entry>libfoo.so.4</entry>
		<entry>libfoo4</entry>
	      </row>
	      <row>
		<entry>libfoo.so</entry>
		<entry>libfoo (But please don't introduce such package!)</entry>
	      </row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	There are packages like libc6, which contain multiple
	shared libraries in one package. This is not encouraged.
	<footnote>
	  <para>	
	    This is the case unless
	    it is confident that shared libraries will not change interfaces 
	    independently, or compatibility issues are carefully handled.
	    In general, when shared libraries are split, there is no reason
	    upstream will keep changes to interfaces synchronised.
	  </para>
	</footnote>
	It becomes more complex and more difficult to handle complex upgrade patterns.
	<ulink url="http://bugs.debian.org/142175">
	  bug#141275, omniorb package contained several different
	  libraries with different SONAME version numbering policies.
	</ulink>
      </para>
      <para>
	There has been a history of packages which were named with 
	the source package name, but it is better practice to name the package 
	according to the library name, for consistency.
	Some old packages are not named this way, such as aalib-dev,
	but new packages should follow the scheme of using the library
	SONAME.
      </para>
      <para>
	For an example of a package which migrated from single-package 
	library file, see xlibs.
	xlibs in Debian 3.0 was one package containing many shared libraries,
	and it is split into multiple packages in later releases of Debian.
	The xlibs package itself is kept as a package which depends on the 
	library packages, so that compatibility and smooth upgrade 
	are ensured.
      </para>
    </section>
    <section id="shlibdependency">
      <title>Dependency of shared libraries, and indirect dependencies.</title>
      <para>
	Shared libraries should depend on what shared libraries it
	depends upon.  There are indirect dependencies, where libA
	depends on libB and libB depends on libC.  In that case, a
	dependency of libA on libC should not be necessary, since the
	dynamic loader will take care of processing such dependencies
	at run-time.  From the Debian perspective, having the indirect
	dependency turned into an explicitly dependency adds to the
	maintenance overhead, since if library libC is upgraded to
	become libC2, and libB is updated to work with libC2, libA
	will be linked with libC and libC2 simultaneously.  This
	usually causes a problem due to having multiple instances of
	similar functions into the memory, and is wasteful having to
	load an unused bit of code.  It will require a rebuild of libA
	to fix the situation, which means Debian archive will need
	quite a few binNMUs.
      </para>
      <para>
	There are a few tricks to avoid this problem.  One is using
	<link linkend="asneeded">--as-needed</link> option, and
	another is using <link linkend="pkgconfig">pkgconfig scripts properly</link>.
      </para>
    </section>
    <section id="shlibsdependonshlibs">
      <title>Shared libraries should link with shared libraries it depends on</title>
      <para>
	Sometimes upstream decides that it is a good idea not to 
	link shared libraries with the depending shared libraries,
	which was the case for libpng<footnote>
	  <para>
	    libpng maintainers considered in 1.2.5 that linking libpng with -lz 
	    was absurd, and removed it.
	    It made a lot of packages fail to build.
	    <ulink url="http://bugs.debian.org/166489">
	      166489
	    </ulink>
	  </para>	  
	</footnote>
	, and some BSD variants.
	That breaks a few things, and thus is not desirable.
	The following are examples of what breaks.
      </para>
      <section>
	<title>dlopen</title>
	<para>
	  dlopen loads shared library, and allows resolving
	  functions in the shared library at run time.
	  The shared library dependency information is used to 
	  resolve the dependencies.
	  Not linking the required shared libraries with the 
	  shared library will result in missing symbols.
	  This bug does not appear very much with <quote>RTDL_GLOBAL</quote>, 
	  but appears more with loading with <quote>RTDL_LOCAL</quote>.
	</para>
      </section>
      <section>
	<title>symbol versioning</title>
	<para>
	  Symbol versioning works at shared library link time,
	  so if the shared library is not linked with 
	  the symbol-versioned shared libraries, 
	  symbol versioning will not work.
	</para>
      </section>
      <section>
	<title>linking with -Bsymbolic</title>
	<para>
	  -Bsymbolic tries to link things with local namespace,
	  and resolves function symbols within the shared library.
	  Not linking will break it.
	  <footnote>
	    <para>This is generally a bad idea and tends to break due to
	      its way of resolving symbols. Use of symbol versioning is
	      recommended.</para>
	  </footnote>
	</para>
      </section>
    </section>
    <section id="shlibsfile"> 
      <title>What to put in shlibs file</title>

      <para> The policy section on "Shared Libraries," and "Handling
	shared library dependencies - the `shlibs' system" has
	explanations about shlibs file.
	<command>dh_makeshlibs</command> creates the required shlibs
	file, in a simple case.
      </para>
      <para> 
	In shlibs file, put something like
      </para>
      <screen>	
	libpcap 0 libpcap0 (&gt;= 0.6.1-1)
      </screen>
      <para>    
	When compatibility breaks, change the SONAME and make it look like
      </para>
      <screen>	
	libpcap 1 libpcap1 
      </screen>
      <para>    
	or, at least give it a different Debian package name
      </para>
      <screen>	
	libpcap 0 libpcap0a
      </screen>
      <para>    
	and create a new libpcap0a package, conflicting with libpcap0
      </para>
      <para>    
	Doing something like :
      </para>
      <screen>	
	libpcap 0 libpcap0 (&gt;= 0.6.1-1), libpcap0 (&lt;&lt; 0.7.0)
      </screen>
      <para>    
	is not good because it will not survive the 
	epoch in the version, and is really unnecessary if 
	SONAMEs are used properly.
      </para>
      <para>
	This is discussed in <link linkend="binarycompat">binary compatibility</link> in detail.
      </para>
    </section>
  </chapter>
  <chapter id="devpkg">
    <title>Development (-DEV) packages</title>
    <section>
      <title>-DEV package names</title>
      <para>
	Package maintainer has two options when naming a shared
	library -DEV package.  One is to name the package after the
	library name and not include the full SONAME, like:
	libfoo-dev.
      </para>
      <para> 
	When naming the package after the full SONAME version
	numbers in the package name, the name is constructed by adding
	the '-dev' suffix to the library package name.	Like the
	following:
      </para>
      <screen>	  
	Package: libfoo2-dev
	Provides: libfoo-dev
	Conflicts: libfoo-dev
      </screen>
      <para>
	The latter is preferred if the library package is widely used,
	and the API is subject to change.
      </para>
      <para>
	Each -DEV package should conflict and provide
	<filename>libfoo</filename> so that no two -DEV package can
	coexist.  This is because the <filename>.so</filename> symlink
	and other files use the same name on shared library package of
	different SONAME.  This is unless the package takes enough
	care to not have duplicate filenames, including
	<filename>.so</filename> symlink, and header file paths.
	Gnome libraries give a good example of such a setup.
      </para>
      <para>
	An example command-line to generate the -DEV package name from 
	a shared library SONAME is as follows:
      </para>
      <screen>
$ objdump -p /usr/lib/libshared.so | \
  sed -n 's/^[[:space:]]*SONAME[[:space:]]*//p' | \
  sed 's/\(0-9\)\.so\./\1/; s/\.so\.//; s/$/-dev/'
libshared0-dev
      </screen>
    </section>
    <section>
      <title>-DEV package dependencies</title>
      <para>
	The -DEV package would usually declare Depends: relationship
	on all -DEV packages for libraries that the library package
	directly depends upon, with the specific SONAME version that the
	library package is linked against. This includes libc-dev.
	<footnote>
	  <para>A package should depend on libc-dev, without versioned
	  depends, or generate different dependencies depending on
	  architectures. Not all architectures have libc-dev as
	  libc6-dev.</para>
	</footnote>
      </para>
      <para>
	The dependency is required to make things such
	as statically linked libraries to work, and C header file inclusions.
	Libtool .la files require dependencies to be present also.
	<footnote>
	  <para>Shared library .so files do not actually require the
	    depending -dev packages at link time, so if upstream was
	    careful enough, it is possible to remove the dependency,
	    if support for static linking is to be dropped.</para>
	</footnote>
	<footnote>
	  <para>
	    libtool .la require all recursive dependencies.
	    pkgconfig .pc files however, do not.
	    See <link linkend="pkgconfig">pkgconfig section for details
	    </link>
	  </para>
	</footnote>
      </para>
      <para> e.g.: 
	libfoo2-dev -&gt; libbar2-dev
	because libfoo2 depends on libbar2
      </para>
      <para>
	This dependency helped in the case of libpng2 and libpng3 to
	avoid libpng2-dev and libpng3-dev to be installed at the same
	time, so that problematic packages could be detected easily.
	<footnote>
	  <para>
	    Bugs like 
	    <ulink url="http://bugs.debian.org/146079">Bug 146079</ulink>
	    go undetected when -DEV packages do not properly depend on other
	    -DEV packages.
	  </para>
	</footnote>
      </para>
      <para> 
	When <filename>libfoo2-dev</filename> that can compile with
	libbar3-dev is required, the SONAME version number of libfoo
	should be bumped up, or a new package containing libfoo linked
	with <filename>libbar3-dev</filename> conflicting with the
	original <filename>libfoo2</filename> needs to be created.
	However this is not enough, as discussed in the <link
	linkend="binarycompat"> binary compatibility section </link>.
      </para>
      <para>	
	<filename>libfoo2-bar3-dev</filename> 
	(which is a development package for a shared library
	package <filename>libfoo2-libbar3</filename> which 
	contains <filename>libfoo.so.2</filename> linked with
	<filename>libbar.so.3</filename>)
	which depends on  <filename>libbar3-dev</filename>
	and has <filename>libfoo2</filename> and 
	<filename>libfoo2-bar3</filename> conflicting with each other.
      </para>
      <para>	
	or 
      </para>
      <para>	
	discuss with upstream to get:
	<filename>libfoo3-dev</filename> for depending upon
	<filename>libbar3-dev</filename>.
	Which is a better solution, which keeps cross-distribution 
	binary-compatibility.
      </para>
      <para>
	There is one exception for this section; 
	the case of libraries with versioned symbols.
	For example, if a -DEV package depends on 
	libdb2-dev, and libdb2-dev has symbols that are versioned
	to allow coexisting with libdb3, 
	it may depend on libdb-dev, and not libdb2-dev.
      </para>
    </section>
    <section>
      <title>Packages which Build-depend on a -DEV package</title>
      <para>	
	It is advised to
      </para>
      <screen>Build-Depends: libfoo[SONAME-version-number]-dev
      </screen>
      <para> 
	(Which needs to be updated every time a new -DEV comes out, and 
	the new SONAME becomes the standard, and the old one becomes obsolete)
      </para>
      <para>	  
	or
      </para>
      <screen>
	Build-Depends: libfoo[SONAME-version-number]-dev | libfoo-dev 
      </screen>
      <para> (this can cause undesired effect of linking with a
	source-incompatible (API-incompatible) library version, i.e. a
	serious "cannot build from source" bug)
      </para>
    </section>
    <section>
      <title>"Build-Depends: libfoo-dev" is not optimal</title>
      <para>	
	The question is:
	Are you really sure all past/present/future version of that 
	-DEV package can be used with the source to build the package?
	(i.e. is your API so fixed in stone that it will never have to be changed?)
	If this is not true, some trouble will happen every time the 
	-DEV package changes.
	<footnote>
	  <para>
	    Stephen Frost commented that: Build-Depend's should be
	    *accurate* in that they map to the *API* that's required.
	    Sometimes this works out as being the same as the SONAME,
	    but that's not always the case.  Multiple ABI's can be
	    associated with a single API.  This is actually the case
	    with OpenLDAP which claims, at least, to have not broken
	    backwards compatibility with the API since the 1.x days,
	    though the ABI has changed a number of times.  Of course,
	    if a package depends on parts of the API that were added
	    later they should version their build-depends
	    appropriately.  In general it'd probably actually be good
	    to get away from having version numbers in -DEV package
	    names based on the expectation that upstream will be
	    similar to the OpenLDAP case, and in the event that the
	    API is changed in a way which is not backwards compatible
	    the library name may be changed in some other way.
	  </para>
	</footnote>
      </para>
    </section>
    <section id="rpath">
      <title>-rpath considered harmful</title>
      <para>
	Use of -rpath is usually discouraged in Debian, since having
	-rpath of /usr/lib will make the dynamic loader behave
	differently, and will have trouble working fine in cases of
	libc5-libc6 transition, and cases where multiple shared
	library versions exist under subdirectories of /usr/lib and
	are selected by ld.so under some criteria.  It will
	potentially break behavior with multiarch, where shared
	libraries are not found in /usr/lib, but under /usr/lib64,
	/usr/lib32, or other places.
      </para>
      <para>
	To remove -rpath in the upstream level, it is usually non-invasive 
	to request upstream to special-case /usr/lib, to not add -rpath.
      </para>
      <para>
	<ulink url="http://lists.debian.org/debian-devel/2002/07/msg02030.html">
	  Richard Atterer summarized his points on his post to debian-devel.
	</ulink>
      </para>
    </section>
    <section id="pkgconfig">
      <title>pkgconfig files</title>
      <para>
	-DEV packages may contain pkgconfig files.  pkgconfig is a
	tool to replace libfoo-config scripts, in a way which is
	integrated with autoconf.
      </para>
      <para>
	pkgconfig has constructs for private shared library linkage,
	as opposed to libtool. libtool will require depending on all
	shared library packages recursively.  Not depending on
	unneeded shared library is a plus for release management.
      </para>
      <para>
	pkgconfig is preferred to libtool, and .la files are in the process of being
	phased out in favor of .pc files.
      </para>
      <para>	    
	Removing .la files and replacing them by pkgconfig files remove the requirement.
	However, the transition needs to be coordinated in leaf-first order, or will cause 
	problems found in libXcursor and libXrender.
	<ulink url="http://bugs.debian.org/363239">Bug# 363239</ulink>
	and 
	<ulink url="http://bugs.debian.org/363057">Bug# 363057</ulink>.
      </para>
    </section>
    <section id="staticonlylibs">
      <title>Can I provide static link library only?</title>
      <para>
	There are cases where the upstream provides only the 
	static link libraries.
	However, doing so is not ideal, because it will
	result in binaries that cannot be rebuilt from source.
	If a newer static library is released since the last
	time a binary package was linked against it, the binary
	package contains code that can no longer be rebuilt 
	from Debian source.
      </para>
      <para>
	There are several reasons for providing static libraries,
	but it is best to avoid it, if it is technically possible.
	Unstable ABI is one reason to provide static libraries for,
	but please reconsider putting such a library package into a
	stable Debian distribution.
      </para>
      <para>
	Providing -fPIC versions of static libraries for linking with shared libraries
	is a bad sign, because the "unstable interface" is now exported through another
	library's stable library interface.
      </para>
      <para>
	<ulink url="http://www.debian.org/security/">
	  zlib vulnerability (DSA122-1) required many packages to be rebuilt from
	  source, because many packages were linked to it statically.
	  It takes much resource to fix such bugs, and if it were 
	  linked dynamically, only one binary package had to be updated.
	</ulink>
      </para>
    </section>
  </chapter>
  <chapter id="upstreamconcerns">
    <title>Handling upstream changes to shared libraries</title>
    <para>
      In this chapter, methods of handling upstream shared libraries
      are discussed.
    </para>
    <section id="upstreambrokensoname">
      <title>How to fix upstream packages with somewhat broken SONAMEs</title>
      <para>
	Refer to libssl and other packages which used to handle it.
	They basically had SONAME version numbers which matched the package
	version, and every version: e.g. 0.9.4 and 0.9.6 had incompatibility.
	The solution was to create a SONAME containing 0.9.6, so that :
      </para>
      <screen>	
	$ objdump -p /usr/lib/libssl.so.0.9.6 | grep SONAME
	SONAME	  libssl.so.0.9.6
      </screen>
      <para>    
	libssl-dev contains the symlink
	<filename>    /usr/lib/libssl.so -&gt; /usr/lib/libssl.so.0.9.6</filename>
      </para>
      <para>    This way, binary programs linked with libssl.so via "-lssl" command
	line option passed to gcc will be looking for libssl.so.0.9.6 at runtime.
      </para>
      <para>    
	It is quite important that Debian does not lose binary compatibility 
	with other distributions, so changing the SONAME specifically for 
	Debian is generally a bad idea. Discuss and convince the upstream to
	use a saner method for determining the SONAMEs.
      </para>
      <para>
	It is however sometimes necessary to add a SONAME for the
	time-being until you have convinced the upstream. Make sure
	you choose a SONAME that is obviously Debian-specific, and be
	prepared for the eventual transition to the upstream-chosen
	SONAME. 
      </para>
    </section>
    <section id="binarycompat">
      <title>When binary compatibility breaks</title>
      <para>    
	SONAME needs to be updated when the binary compatibility is broken.
      </para>
      <para>    
	When the library itself changes the interface, the SONAME 
	needs to be changed, because the binary compatibility has changed.
      </para>
      <para>    
	Also, when the library that the library depends on has changed incompatibly,
	it means that the library depending on the changed library has 
	changed incompatibly. i.e. if the library will need to link to a 
	shared library with a different soname than it had previously,
	the soname needs to be modified.
      </para>
      <para>    
	The SONAME needs to be modified to reflect this change.
      </para>
      <para>    
	However, it is not always possible to increase the SONAME version number,
	possibly to remedy past problems, and experiences.
	To do that, it is also possible to change just the package name.
	Note that it is the best to modify the SONAME in the upstream level,
	because recompiling with a new package name will solve problems within the Debian
	packages, but it will not solve problems with the user 
	compiled binaries in 
	places such as <filename>/usr/local/</filename>. 
	Also it might cause problems with software that is distributed in 
	binary-only form, which expects to have some shared library 
	with a specific interface.
	Debian supports the use of such 
	binaries, and packages should not break them.
	Therefore the method described here should only be 
	used as a last resort.
	It is better than changing the binary interface and not changing
	the library package name or soname
	<footnote>
	  <para>
	    <link linkend="libsdlimagepng3">libsdl-image1.2 recompiled
	  with libpng3 while it was previously linked with libpng2 and
	  broke many packages</link>
	  </para>
	</footnote>
      </para>
      <para>
	It is strongly discouraged to create a shlibs file containing
	a (= VERSION) relationship, or (&gt; VERSION) and (&lt;
	VERSION) relationship. Such packages should not be released as
	stable.
      </para>
      <para>    
	<filename>libfooX</filename> may have been broken, and to fix it, introduce a new package
	<filename>libfooXSOMETHING</filename>. Alter the shlibs files so that building with
	<filename>libfooX-dev</filename> will cause the binary package to depend on 
	<filename>libfooXSOMETHING</filename>, like the following:
      </para>
      <screen>
	libfoo X libfooXSOMETHING 
      </screen>
      <para>    
	Also <filename>libfooXSOMETHING </filename> 
	should have the following package information:
      </para>
      <screen>	
	Package: libfooXSOMETHING
	Provides: libfooX
	Conflicts: libfooX
      </screen>
      <para>
	to reflect that
	<filename> libfooXSOMETHING</filename> is not installable alongside with
	libfooX. 
	A package rename is necessary, because such relationship is 
	very difficult to express without a package rename, and 
	without one, problems such as described in bug #155938 may occur.
      </para>
      <para>    
	And start recompiling every package that is linked against 
	libfooX against the libfooX-dev, updating the Build-Depends 
	accordingly (to build-depend on a version greater than the newly 
	created libfooX-dev). 
      </para>
      <screen>	    
	apt-cache rdepends libfooX
      </screen>
      <para>    
	or
      </para>
      <screen>	
	grep-available -F Depends -s Package,Depends libfooX
      </screen>
      <para>    
	will give a rough idea of what needs to be done (although possibly 
	not complete).
      </para>
      <para> 
	This whole process needs a lot of interaction between
	developers.  The individual maintainers need to be notified,
	and some discussion and coordination through
	debian-release@lists.debian.org, and possibly
	debian-devel@lists.debian.org mailing list is recommended.  It
	usually takes order of several months to get something like this
	fixed, and it is best to avoid such change.
      </para>
      <para>
	Also note the implication on the <quote>testing</quote> release model of Debian.
	Library binary-package name changes currently require manual 
	intervention and <quote>hinting</quote> for migration into the <quote>testing</quote> distribution,
	since a set of packages 
	needs to migrate from <quote>unstable</quote> to <quote>testing</quote> in one set.
	This is true when the library source package name is unchanged,
	and the version in unstable cannot coexist with the version
	in <quote>testing</quote> in the source archive; meaning that the old package 
	with the old soname will be removed from <quote>testing</quote>.
	This is due to the fact that multiple packages depend on 
	a shared library, and these packages need to be updated at the 
	same time.
      </para>
      <table>
	<title>References for broken SONAME upgrades and packages </title>
	<tgroup cols="2">
	  <colspec colnum="1" colname="c1" colwidth="1*" align="left" />
	  <colspec colnum="2" colname="c2" colwidth="3*" align="left" />
	  <tbody>
	    <row>
	      <entry>	 
		SDL
	      </entry>
	      <entry>	    
		<ulink url="http://lists.debian.org/debian-devel/2001/debian-devel-200110/msg00353.html">
		  http://lists.debian.org/debian-devel/2001/debian-devel-200110/msg00353.html</ulink>
	      </entry>
	    </row>
	    <row>
	      <entry>	 
		libpng
	      </entry>
	      <entry id="libsdlimagepng3">
		<ulink url="http://lists.debian.org/debian-devel/2002/debian-devel-200201/msg00243.html">
		  http://lists.debian.org/debian-devel/2002/debian-devel-200201/msg00243.html</ulink>, 
		discussion about png transition and qt2.
		
		<ulink url="http://bugs.debian.org/147707">Bug 147707:</ulink> should libpng2 conflict with old 
		gimp?, commenting about problems with sonames not changing when binary 
		compatibility is broken.

		<ulink url="http://bugs.debian.org/153813" >
		  Bug 153813</ulink>:
		libsdl-image1.2 relinked from libpng2 to libpng3 
		without changing the soname.
		causing libsdl-perl to break,
		causing frozen-bubble to break.
		Upgrade from woody will break even if this ad-hoc fix
		is installed.

		<ulink url="http://bugs.debian.org/155938">
		  Bug 155938</ulink>:
		libsdl-perl and libsdl-image1.2 in sarge (testing)
		got out of sync, although libsdl-image1.2 problem
		(linking with libpng3) was addressed with random
		recompilation of packages within sid,
		their migration to testing caused similar 
		problem, because there was no dependency 
		tracking information.
	      </entry>
	    </row>      
	    <row>
	      <entry>
		slang-utf8
	      </entry> 
	      <entry>	
		<ulink url="http://lists.debian.org/debian-devel/2002/debian-devel-200201/msg02539.html">
		  Trying to fix slang post in debian-devel mailing list</ulink></entry>
	    </row>
	    <row>
	      <entry>	 
		libsmpeg0
	      </entry>
	      <entry>
		<ulink url="http://bugs.debian.org/140572">
		  libsmpeg0 naming problem, should have been 
		  libsmpeg0-4, bug 140572
		</ulink>
	      </entry>
	    </row>      
	    <row>
	      <entry>	  
		liby2
	      </entry>
	      <entry>
		liby2 contained liby2.so.7, or liby2.so.12, but the 
		package name was same from potato to woody.
		<ulink url="http://bugs.debian.org/140753">
		  http://bugs.debian.org/140753 (xshipwars, a package depending on liby2)
		</ulink>
		<ulink url="http://bugs.debian.org/138815">
		  http://bugs.debian.org/138815 (liby2 fix)
		</ulink>
	      </entry>
	    </row>
	    <row>
	      <entry>clanlib</entry>
	      <entry>
		<ulink url="http://bugs.debian.org/140976">
		  clanlib SONAME version number is upgraded from .1 to .2 without
		  changing package name: Bug 140976
		</ulink>
	      </entry>
	    </row>
	    <row>
	      <entry>libsnmpkit1</entry>
	      <entry>
		<ulink url="http://bugs.debian.org/145462">
		  pconf-detect was broken by libsnmpkit1 when
		  the package was silently upgraded 
		  with libsnmpkit.so.2 included.
		  Obviously, the maintainer didn't test the binaries,
		  only compiled the shared libraries and uploaded.
		</ulink>
	      </entry>
	    </row>
	    <row>
	      <entry>libmotif</entry>
	      <entry>
		<ulink url="http://bugs.debian.org/150635">
		  libmotif: soname changed without package name change.
		</ulink>
		libmotif used to contain libXm.so.2, but it now contains
		libXm.so.3, with the same package name.
	      </entry>
	    </row>
	    <row>
	      <entry>libvorbis</entry>
	      <entry>
		libvorbis0 package was split into libvorbisfile3
		etc packages without changing package name.
		Causing many breakages.
		<ulink url="http://bugs.debian.org/154699">broken ogg123.</ulink>
		<ulink url="http://bugs.debian.org/154704">broken defendguin.</ulink>
		<ulink url="http://bugs.debian.org/154744">frozen-bubble breakage..</ulink>
		<ulink url="http://bugs.debian.org/154699">libvorbis upgrade breaks many apps.</ulink>
		<ulink url="http://bugs.debian.org/154680">libsdl-mixer1.2 breakage.</ulink>
		<ulink url="http://bugs.debian.org/154765">xmms breakage.</ulink>

	      </entry>
	    </row>
	  </tbody>
	</tgroup>
      </table>
    </section>
    <section id="sonamenomodify">
      <title>What kind of change is permitted without soname change and when do I need to change it?</title>
      <para>
	This part of shared library packaging guide is focused more on 
	shared library upstream maintainers, rather than Debian.
	Since Debian is one of the largest binary distribution around, 
	Debian is the one who will experience problems from 
	what others do.
      </para>
      <para>
	There are cases where the SONAME does not have to change when 
	the source code changed.
	For example, when a new function symbol is introduced
	and existing symbols are not modified, it is a backward-compatible change.
	Old programs linked to the library will work with the new library.
	New programs compiled against the new library will not work 
	with the old library, so this needs to be noted in the shared library dependency.
	<footnote>
	  <para>	However, remember to change the last digit of the shared library file, 
	    since some Operating Systems other than Linux do not allow online replacement of 
	    files with the same name.
	    One of the reasons
	    for the libfoo.so.X symbolic link pointing to libfoo.so.X.Y.Z.
	  </para>
	</footnote>
	This is the case where one would use dh_makeshlibs -V option; 
	adding a (&gt;= VERSION) relationship.
	<footnote>
	  <para><ulink url="http://lists.debian.org/debian-devel/2005/06/msg02017.html">
	  librote (A thread discussing an example of compatible change.)
	    </ulink></para>
	</footnote>
      </para>
      <para>
	<link linkend="changesandeffectstable">Changes and effects</link> is a rough list of cases.
      </para>
      <table id="changesandeffectstable">
	<title>Changes and effects</title>
	<tgroup cols="4">
	  <colspec colnum="1" colname="c1" colwidth="5*" align="left" />
	  <colspec colnum="2" colname="c2" colwidth="1*" align="left" />
	  <colspec colnum="3" colname="c3" colwidth="1*" align="left" />
	  <colspec colnum="4" colname="c4" colwidth="1*" align="left" />
	  <thead>
	    <row>
	      <entry>Change</entry>
	      <entry>SONAME</entry>
	      <entry>shared library filename</entry>
	      <entry>Debian versioning</entry>
	    </row>
	  </thead>
	  <tbody>
	    <row>
	      <entry>Removing a function, changing a semantic of function</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	    </row>
	    <row>
	      <entry>Changing a struct incompatibly</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	    </row>
	    <row>
	      <entry>Adding a function</entry>
	      <entry>keep</entry>
	      <entry>change</entry>
	      <entry>Add depends on &gt;=</entry>
	    </row>
	    <row>
	      <entry>Depending library changes SONAME (without versioned symbols)</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	    </row>
	    <row>
	      <entry>Depending library changes SONAME (with versioned symbols)</entry>
	      <entry>keep</entry>
	      <entry>change</entry>
	      <entry>Add depends on &gt;=</entry>
	    </row>
	    <row>
	      <entry>Changing byte-packing behavior, compiler options</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	      <entry>change</entry>
	    </row>
	  </tbody>
	</tgroup>
      </table>
    </section>
    <section id="sonameoftenchange">
      <title>What to do when SONAMEs change too often</title>
      <para>    
	There are some cases where the library SONAMEs change too often.
	It might be a legitimate thing, but the upstream may be doing it
	just for the sake of it.
	Check their modifications, and suggest to increase the SONAME 
	version number
	only when the library has an incompatible change.
      </para>
      <para>    
	When you only see ChangeLog file and configure.in and 
	such files being modified, and yet you see SONAME changes,
	it is a good sign that the upstream is not taking SONAMEs seriously.
      </para>
      <para>    
	There are libraries which are under heavy development.
	It is a pain anyway, because people have to follow it,
	accept that it is a pain. It is almost impossible to package 
	a moving target into a stable distribution.
      </para>
      <para>    
	As a temporary measure such fast moving libraries can be built as .a
	libraries and statically linked to. This ensures that binaries contain
	the object files they were compiled against. Be careful though, while
	this removes the need of an ever increasing SONAME version number, 
	doing this can cause
	problems later if these static libraries are used in shared objects of other
	packages. And also, this does not solve everything.
	Library packages are constantly evolving for a reason.
      </para>
      <para>
	Using statically linked libraries open up a can of worms.
	Even if upstream does not come up with a shared library,
	it might be better to use the -release flag to add a Debian
	specific version string, like debian.20020512.
	Constructing the version number including the string 
	debian, and the date should make the version number
	unique.
      </para>
      <para>
	<ulink url="http://lists.debian.org/debian-devel/2002/debian-devel-200201/msg01772.html"> There was a problem with libgal SONAME changing too rapidly, which caused people to work around it in all sorts of strange ways.
	</ulink>
      </para>
    </section>
  </chapter>

  <chapter id="libraryfromsinglesource">
    <title>Consideration when building binary package and library package from single source</title>
    <para>
      When building packages which have binaries linked against the 
      shared library built from the same source, 
      a trick is required to properly set the Depends: line.
    </para>
    <para>
      Create a <filename>debian/shlibs.local</filename> 
      file containing the necessary dependency 
      information, and add the shared library location to LD_LIBRARY_PATH.
      <filename>shlibs.local</filename> should contain something in the 
      line of <type>SONAME-before.so SONAME-after.so package-name</type>,
      which is documented in the policy manual.
    </para>
    <para>
      When using debhelper, such can be achieved by:
      <command>
	dh_shlibdeps -LlibfooX -l${PWD}/debian/libfooX/usr/lib
      </command>
    </para>
  </chapter>
  <chapter id="linkertricks">
    <title>Advanced linker tricks</title>
    <section id="asneeded">
      <title>Only linking shared library as needed</title>
      <para>
	GNU ld has an extention to only link shared libraries that
	have used symbols, thus removing unnecessary linkages.
	Unneeded linkages are maintenance burden, and although it
	should really be fixed manually, having an automated help is
	usually a good idea.
	It can be used as the following:
      </para>
      <para>
	<screen>
LDFLAGS="-Wl,--as-needed" ./configure --prefix=/usr [...]
	</screen>
      </para>
      <para>
	<ulink url="http://bugs.debian.org/347650">Note that currently
	libtool has a bug that it reorders argument, which breaks
	passing --as-needed option to ld.</ulink>
      </para>
    </section>
    <section id="exportregex">
      <title>Only exporting required functions</title>
      <para>
	It is possible to use -export-symbols-regex option of libtool to restrict 
	symbols exported from the shared library.
	It is usually a good idea to do so since unexpected exported symbols can be a problem
	due to namespace and other issues.
	You can use this method, or the method explained in <link linkend="symbolversioning">symbol versioning.</link>
	To use this feature, it's simple.
	This is an example Makefile.am snippet for libSDL_mixer, to export only  
	functions that match the regular expression (regex) <command>Mix_.*</command>
      </para>
      <para>
	<screen>
libSDL_mixer_la_LDFLAGS =       \
[...]
        -export-symbols-regex Mix_.*
	</screen>
      </para>
    </section>
    <section id="symbolversioning">
      <title>Symbol Versioning for shared libraries</title>
      <para>
	Sometimes, multiple versions of shared library in distribution
	is a social problem. The reasoning being that 
	other maintainers are not willing to rebuild their packages 
	against new versions of shared libraries.
	However, there are cases where it is necessary to retain 
	compatibility with older versions of shared library;
	especially when dlopen is used, and the application is not 
	going to be restarted through upgrades.
	PAM, and some daemons are affected by this.
	This effectively requires most of Debian base system to be 
	eventually versioned, to allow seamless upgrades.
      </para>
      <para>
	<ulink url="http://www.debconf.org/debconf4/talks/dependency-hell/index.html">
	  A presentation was given by Steve Langasek in Debconf4, Brazil.</ulink>
	The libpkg-guide originally presented a strategy of -DEV packages
	conflicting with each other; 
	it did not scale very well, and caused much disruptions.
	To ease transition of changing library SONAMEs, it is possible to 
	use versioned symbols in shared library and allow multiple 
	versions of the same shared library to coexist within single application
	instance.
      </para>
      <section>
	<title>Symbol versioning</title>
	<para>
	  Symbol versioning is a linker trick where functions are
	  treated as if they were prefixed by a specific symbol.
	  For example, if there are two different libraries libA and libB
	  providing one "initialize" function, it is possible to
	  symbol-version them so that binaries will try to resolve
	  libA@initialize and libB@initialize so that they can
	  coexist within the same shared library namespace.
	</para>
      </section>
      <section id="sharedversionlibhowto">
	<title>How to make a shared library package with versioned symbol</title>
	<para>
	  Adding options <command><parameter>-Wl,--version-script,<replaceable>dsh.ver</replaceable></parameter></command> to gcc or libtool allows using the version script for versioning of shared library.
	</para>
	<para>
	  A version script will look like this:
	  <screen>
HIDDEN {
local:
    __*;
    _rest*;
    _save*;
};

libdshconfig0 {
    *;
};
	  </screen>
	</para>
	<para>
	  HIDDEN part is required to hide some symbols from being versioned.
	  This example will add a version "libdshconfig0" to the exported symbols defined within the library.
	  To verify that the symbols are versioned, <command>objdump -T</command> can be used. A snippet of output looks like this:
	  <screen>
00000000      DO *UND*	00000004  GLIBC_2.0   stderr
00000e04 g    DF .text	00000048  libdshconfig0 free_dshconfig
00000dc4 g    DF .text	0000003f  libdshconfig0 free_dshconfig_internal
00000000 g    DO *ABS*	00000000  HIDDEN      HIDDEN
00000ed0 g    DF .fini	00000000  libdshconfig0 _fini
	  </screen>
	  The name of the version symbol needs to be unique across all shared libraries within Debian, and it should be a good idea to derive the string from the shared library SONAME.
	</para>
	<para>
	  Not all Operating systems support versioned symbols, 
	  and usually making the script optional would be required.
	  You may use autoconf/automake checks to make the option configurable. 
	  An example of doing such check can be found in libdshconfig.
	  The following snippet is added to configure.ac to check for 
	  <command><parameter>--with-versioned-symbol</parameter></command> option to configure script invocation:
	</para>
	<screen>
	  vsymldflags=
	  AC_MSG_CHECKING([version script options])
	  AC_ARG_WITH([versioned-symbol],AC_HELP_STRING([--with-versioned-symbol],[Use versioned symbols]),[dnl
	  vsymldflags="-Wl,--version-script,dsh.ver -Wl,-O1"
	  ])
	  AC_SUBST(vsymldflags)
	  AC_MSG_RESULT([${vsymldflags}])
	</screen>
	<para>
	  The following snippet is added to Makefile.am to actually add ld flags for versioned symbol.
	</para>
	<screen>
	  lib_LTLIBRARIES = libdshconfig.la
	  libdshconfig_la_LDFLAGS = -export-dynamic -version-info $(DSHCONFIG_SONAME) @vsymldflags@
	</screen>
      </section>
      <section>
	<title>Migration strategy</title>
	<para>
	  To enable symbol versioning on two different shared libraries
	  which were previously not versioned,
	  all binaries need to be rebuilt against the versioned
	  shared library.
	</para>
	<para>
	  Enabling versioned symbol does not 
	  break binary compatibility, and it is be easier and less disruptive to 
	  just enable versioned symbols and rebuild all other
	  binaries depending on the shared library, to avoid too much 
	  disruptions to the Debian archive.
	  However, make sure enough time is given for the library to build
	  to get all architectures synchronized.
	  <footnote>
	    <para>	  
	      Note also that this assumes that user is going to 
	      perform dist-upgrade to upgrade all packages at once, 
	      and does not support the use of individual upgrades.
	    </para>
	  </footnote>
	</para>
	<para>
	  Note that, to be pedantic, the new library needs to conflict 
	  with binaries which were linked against the unversioned 
	  shared library.
	  This is discussed in <link linkend="binarycompat">
	    binary compatibility section
	  </link>.
	  Say the library package was originally named libunversion0.
	  The most pedantic way to ensure this effect is to
	  change the shared library package name to libunversion0v, 
	  and conflict with libunversion0, so that 
	  every binary package built against the versioned 
	  shared library will show up in the Depends: field.
	  This process will be disruptive and make many packages uninstallable,
	  and should be used with care.
	</para>
      </section>
      <section id="versymproblems">
	<title>Possible problem cases</title>
	<para> 
	  Symbol versioning only versions function/variable name symbols,
	  and does not version structures etc, so it does not solve problems
	  with mixed protocols, data structures and other things with
	  mixed versions of shared library. Thus, it is not a silver 
	  bullet for all cases.
	</para>
	<para>
	  Symbol versioning only handles shared libraries, and 
	  it will not help with statically linked libraries.
	</para>
	<para>
	  Also there is a possibility of breakage in the transition phase. 
	  When binary A is linked against unversioned libpng.so.2 and libB,
	  and old libB was linked against unversioned libpng.so.2.
	  libB is now linked against versioned libpng.so.3, and 
	  upgrading libB may cause failures.
	</para>
	<para>
	  The dynamic linker is intelligent enough to handle cases when 
	  the new library is only available as versioned symbols, 
	  and the older library is only available as unversioned symbol.
	</para>
	<para>
	  <ulink url="http://bugs.debian.org/140490">Bug 140490 is for some symbols that should not be versioned. You need to be restrictive about what symbols to version.</ulink>
	</para>
	<para>
	  libdb transition was painful, but it was completed.
	</para>
      </section>
      <section>
	<title>Supported architectures</title>
	<para>
	  All architectures that are in the Debian distribution support
	  symbol versioning.
	  But it should be noted that each architecture has its list of symbols that 
	  should not be versioned.
	</para>
      </section>
      <section>
	<title>Some references on symbol versioning</title>
	<para>
	  <ulink url="http://lists.debian.org/lsb-spec/1999/lsb-spec-199912/msg00017.html">
	    "ELF symbol versioning with glibc 2.1 and later" from Ulrich Drepper</ulink>
	  and Info manual for "ld" has some documentation.
	</para>
      </section>
    </section>
  </chapter>
  <chapter id="dlopenimplies">
    <title>dlopened modules and implication of dlopening</title>
    <para>
      Many basic library packages freely use dlopen as a method for loading shared library symbols 
      dynamically. Examples are glibc and PAM. There are several advantages and disadvantages.
      For advantages:
    </para>
    <itemizedlist>
      <listitem>
	<para>Dynamic loading allows dynamic library dependency</para>
      </listitem>
      <listitem>
	<para>No fork/exec/pipe/ipc overhead for extra functionality, and allows easy code sharing</para>
      </listitem>
      <listitem>
	<para>Allows use of library code without intermediate interfacing</para>
      </listitem>
    </itemizedlist>
    <para>
      Disadvantages:
    </para>
    <itemizedlist>
      <listitem>
	<para>Cannot take advantage of prelinking</para>
      </listitem>
      <listitem>
	<para>Introduces untested combinations of shared libraries</para>
      </listitem>
      <listitem>
	<para>Shared library being dlopened may change while the applications are running (e.g. when upgrading);
	  glibc worked around this problem by giving an option
	  of reloading affected binaries.</para>
      </listitem>
    </itemizedlist>
    <para>
      There were a few problem cases with this situation.
      PAM_ldap dlopened ldap libraries, which depended on a chain of shared libraries such as libssl.
      However, ssh and ldap did not agree on which version of libssl to depend upon,
      and ssh ended up loading two different libssl versions into the same function namespace
      when PAM was configured with ldap.
    </para>
    <para>
      A problem happened when glibc changed incompatibly regarding libnss.
      An application that started up with the older version of 
      glibc would crash, if upgraded version of libnss was loaded.
      libnss loading was triggered by nameserver lookups, for example.
    </para>
    <para>
      Similar problem appeared when GTK themes used libpng2. 
      Because GTK pixmap theme uses libpng2, and GTK applications dlopen theme engines,
      GTK applications that are linked with libpng3 resulted in load failures when 
      the pixmap engine was specified as the theming engine.
    </para>
    <para>
      This situation cannot be avoided with strict -DEV versioning and dependency as described in this
      paper.
    </para>
    <para>
      If a library or application does a dlopen to use a module, 
      that module and its chain of dependencies have a chance 
      of two different versions of the same module being loaded at the same time.
      Unless RTDL_GROUP option for dlopen gets implemented and gets used, 
      there are basically two options to avoid problems:
    </para>
    <itemizedlist>
      <listitem>
	<para>
	  Uniquely named symbols, differently between different SONAMES.
	</para>
      </listitem>
      <listitem>
	<para>
	  Version the symbols using symbol versioning as described in <xref linkend="symbolversioning" />.
	</para>
      </listitem>
    </itemizedlist>
  </chapter>
  <chapter id="libraryloading">
    <title>How shared library is loaded</title>
    <para>
      This is an informational section.
      This section is targeted at Debian Developers 
      who need to explain convincingly to upstream developers 
      on why symbols should be versioned, and 
      why things should be as it is.
      This section explains how an ELF shared library is loaded with  
      Linux kernel and glibc.
      <ulink url="http://people.redhat.com/drepper/dsohowto.pdf">
	Ulrich Drepper's writeup on DSO's has a more detailed account on this topic.
      </ulink>
    </para>
    <para>
      When an ELF header is found by ELF handler inside Linux Kernel
      <footnote>
	<para>
	  As of linux 2.6.9, the relevant code is found in fs/binfmt_elf.c
	</para>
      </footnote>
,
      it will invoke the executable found in the ELF .interp section.
      <footnote>
	<para>	The command to check is: objdump -s -j.interp testprint</para>
      </footnote>
      The dynamic loader, which usually is /lib/ld.so.1; which itself usually 
      is a static ELF binary.
      <footnote>
	<para>	
	  The source-code to ld.so lies in glibc source tree, 
	  elf/rtld.c
	</para>	     
      </footnote>
      Dynamic loader will interpret the ELF header and perform the rest of 
      loading.
    </para>
    <para>
      The functions from the shared library are loaded to memory 
      in a relocated address.
      Which is determined at the time ld.so loads the shared library.
      <footnote>
	<para>	The introduction of prelink has changed this 
	since prelink will scan the system and calculate 
	the relocation in a batch process rather than at load time.
	</para>
      </footnote>
      The important point to note is that the assembly command to call
      the subroutine will require a memory address where the 
      code is located, but that is not calculated at the time 
      of compiling, linking, or package building.
      ld.so uses the function names embedded in the 
      shared library (called symbols) and resolves the 
      symbols through name-matching.
    </para>
    <para>
      Let us see with live example.
      The following is a binary <filename>testprint</filename>
      which is linked to the shared library <filename>libshared</filename>
      which defines some symbols like <function>shared_new</function>.
      The code itself looks like this when disassembled through gdb:
      <footnote>
	<para>To see what ld.so thinks it is doing, running an application with 
      environmental variable LD_DEBUG=all set.</para></footnote>
    </para>
    <screen>
Dump of assembler code for function main:
0x10001650 &lt;main+0&gt;:    stwu    r1,-32(r1)
0x10001654 &lt;main+4&gt;:    mflr    r0
0x10001658 &lt;main+8&gt;:    stw     r31,28(r1)
0x1000165c &lt;main+12&gt;:   stw     r0,36(r1)
0x10001660 &lt;main+16&gt;:   bl      0x10011c00 &lt;shared_version&gt;
0x10001664 &lt;main+20&gt;:   bl      0x10011be8 &lt;shared_new&gt;
0x10001668 &lt;main+24&gt;:   cmpwi   r3,0
0x1000166c &lt;main+28&gt;:   mr      r31,r3
0x10001670 &lt;main+32&gt;:   beq-    0x100016a0 &lt;main+80&gt;
0x10001674 &lt;main+36&gt;:   li      r0,10
0x10001678 &lt;main+40&gt;:   li      r9,20
0x1000167c &lt;main+44&gt;:   stw     r0,0(r3)
0x10001680 &lt;main+48&gt;:   stw     r9,4(r3)
0x10001684 &lt;main+52&gt;:   bl      0x10011be0 &lt;shared_print&gt;
0x10001688 &lt;main+56&gt;:   mr      r3,r31
0x1000168c &lt;main+60&gt;:   bl      0x10011c08 &lt;shared_free&gt;
0x10001690 &lt;main+64&gt;:   cmpwi   r3,0
0x10001694 &lt;main+68&gt;:   beq-    0x1000169c &lt;main+76&gt;
0x10001698 &lt;main+72&gt;:   li      r3,1
0x1000169c &lt;main+76&gt;:   bl      0x10011bf8 &lt;exit&gt;
0x100016a0 &lt;main+80&gt;:   lis     r3,4096
0x100016a4 &lt;main+84&gt;:   lis     r4,4096
    </screen>
    <para>
      The jump target is also a list of jump targets, which is called the GOT.
      Exact details are different, but on powerpc, they are initially 
      entries to set an identifier for the function entry on r11 register, 
      and jump to the dynamic linker.
      The dynamic linker will resolve the symbol and write a branch 
      instruction to that address of GOT.
      The next time the function call happens, the 
      new branch command is used.
      The initial call costs at least three branches to call the function,
      but the next call will cost two jumps.
    </para>
    <screen>
(gdb) break 13
Breakpoint 1 at 0x10001664: file testprint.c, line 13.
(gdb) run
Starting program: /home/dancer/cvscheckout/whole/shlib-demo/libshared/.libs/testprint
libshared 0.1

Breakpoint 1, main (argc=14, argv=0x30080674) at testprint.c:13
13	  dat = shared_new();
(gdb) list
8	int main(int argc, char **argv)
9	{
10	  shareddata* dat;
11
12	  shared_version();
13	  dat = shared_new();
14	  assert (dat);
15	  dat-&gt;flag1=10;
16	  dat-&gt;flag2=20;
17	  shared_print(dat);
    </screen>
    <screen>
0x10011bd8 &lt;__assert_fail+0&gt;:   li      r11,0
0x10011bdc &lt;__assert_fail+4&gt;:   b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011be0 &lt;shared_print+0&gt;:    li      r11,4
0x10011be4 &lt;shared_print+4&gt;:    b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011be8 &lt;shared_new+0&gt;:      li      r11,8
0x10011bec &lt;shared_new+4&gt;:      b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011bf0 &lt;__libc_start_main+0&gt;:	      li      r11,12
0x10011bf4 &lt;__libc_start_main+4&gt;:	      b	      0x10011b90 &lt;__JCR_LIST__+24&gt;
Dump of assembler code from 0x10011c00 to 0x10011cff:
0x10011c00 &lt;shared_version+0&gt;:  b	      0xffaea60 &lt;shared_version&gt;
0x10011c04 &lt;shared_version+4&gt;:  b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011c08 &lt;shared_free+0&gt;:     li      r11,24
0x10011c0c &lt;shared_free+4&gt;:     b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
    </screen>
    <para>
      After executing the function, the slot is replaced with a direct branch
      to the target function.
    </para>
    <screen>
(gdb) cont
Continuing.

Breakpoint 2, main (argc=268509264, argv=0x10012058) at testprint.c:14
14	  assert (dat);
(gdb) disassemble 0x10011be0 0x10011bff
Dump of assembler code from 0x10011be0 to 0x10011bff:
0x10011be0 &lt;shared_print+0&gt;:    li      r11,4
0x10011be4 &lt;shared_print+4&gt;:    b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011be8 &lt;shared_new+0&gt;:      b	      0xffaeb14 &lt;shared_new&gt;
0x10011bec &lt;shared_new+4&gt;:      b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
0x10011bf0 &lt;__libc_start_main+0&gt;:	      li      r11,12
0x10011bf4 &lt;__libc_start_main+4&gt;:	      b	      0x10011b90 &lt;__JCR_LIST__+24&gt;
0x10011bf8 &lt;exit+0&gt;:    li      r11,16
0x10011bfc &lt;exit+4&gt;:    b	      0x10011bb0 &lt;__JCR_LIST__+56&gt;
End of assembler dump.
    </screen>
    <para>
      The relevant part that is jumped to before initialization is here:
    </para>
    <screen>
0x10011bb0 &lt;__JCR_LIST__+56&gt;:   rlwinm  r12,r11,1,0,30
0x10011bb4 &lt;__JCR_LIST__+60&gt;:   add     r11,r12,r11
0x10011bb8 &lt;__JCR_LIST__+64&gt;:   li      r12,-19048
0x10011bbc &lt;__JCR_LIST__+68&gt;:   addis   r12,r12,4094
0x10011bc0 &lt;__JCR_LIST__+72&gt;:   mtctr   r12
0x10011bc4 &lt;__JCR_LIST__+76&gt;:   li      r12,0
0x10011bc8 &lt;__JCR_LIST__+80&gt;:   addis   r12,r12,12288
0x10011bcc &lt;__JCR_LIST__+84&gt;:   bctr
0x10011bd0 &lt;__JCR_LIST__+88&gt;:   .long 0x0
0x10011bd4 &lt;__JCR_LIST__+92&gt;:   .long 0x0
    </screen>
    <para>
      The binary that is linked to the library has a list of relocations, 
      that will need to be filled up when
      the binary is loaded.
    </para>
    <screen>
$ objdump -R testprint 

.libs/testprint:     elf32-powerpc

DYNAMIC RELOCATION RECORDS
OFFSET	 TYPE		   VALUE 
10011b8c R_PPC_GLOB_DAT	   __gmon_start__
10011bd8 R_PPC_JMP_SLOT	   __assert_fail
10011be0 R_PPC_JMP_SLOT	   shared_print
10011be8 R_PPC_JMP_SLOT	   shared_new
10011bf0 R_PPC_JMP_SLOT	   __libc_start_main
10011bf8 R_PPC_JMP_SLOT	   exit
10011c00 R_PPC_JMP_SLOT	   shared_version
10011c08 R_PPC_JMP_SLOT	   shared_free
    </screen>
    <para>
      The shared library only holds a relative location;
      and their location needs to be calculated after loading.
    </para>
    <screen>
$ objdump -t libshared.so| grep shared 
libshared.so:  file format elf32-powerpc
00000000 l    df *ABS*	00000000	      shared.c
00001aac g     F .text	00000068	      shared_print
00001b14 g     F .text	00000040	      shared_new
00001a60 g     F .text	00000048	      shared_version
00001b54 g     F .text	00000038	      shared_free
    </screen>
    <para>
      The memory map of loaded binary can be seen through 
      <filename>/proc/XXX/maps</filename> file.
    </para>
    <screen>
$ cat /proc/32396/maps
0ffad000-0ffaf000 r-xp 00000000 03:04 1160506	 /work/libshared.so.0.0.0
0ffaf000-0ffbd000 ---p 00002000 03:04 1160506	 /work/libshared.so.0.0.0
0ffbd000-0ffc0000 rwxp 00000000 03:04 1160506	 /work/libshared.so.0.0.0
0ffd0000-0ffe6000 r-xp 00000000 03:04 162950	 /lib/ld-2.3.2.so
0fff6000-0fff7000 rwxp 00016000 03:04 162950	 /lib/ld-2.3.2.so
10000000-10002000 r-xp 00000000 03:04 1160514	 /work/testprint
10011000-10012000 rwxp 00001000 03:04 1160514	 /work/testprint
30000000-30002000 rw-p 30000000 00:00 0
3000d000-3013f000 r-xp 00000000 03:04 162953	 /lib/libc-2.3.2.so
3013f000-3014d000 ---p 00132000 03:04 162953	 /lib/libc-2.3.2.so
3014d000-3015a000 rwxp 00130000 03:04 162953	 /lib/libc-2.3.2.so
3015a000-3015c000 rwxp 3015a000 00:00 0
7fffe000-80000000 rwxp 7fffe000 00:00 0
    </screen>
    <para>
      Shared library symbols originally look like:
    </para>
    <screen>
(gdb) disassemble shared_free
Dump of assembler code for function shared_free:
0x0ffaeb54 &lt;shared_free+0&gt;:     cmpwi   r3,0
0x0ffaeb58 &lt;shared_free+4&gt;:     stwu    r1,-32(r1)
0x0ffaeb5c &lt;shared_free+8&gt;:     mflr    r0
0x0ffaeb60 &lt;shared_free+12&gt;:    li      r9,1
0x0ffaeb64 &lt;shared_free+16&gt;:    stw     r0,36(r1)
0x0ffaeb68 &lt;shared_free+20&gt;:    beq-    0xffaeb78 &lt;shared_free+36&gt;
0x0ffaeb6c &lt;shared_free+24&gt;:    crclr   4*cr1+eq
0x0ffaeb70 &lt;shared_free+28&gt;:    bl      0xffbf19c &lt;__JCR_LIST__+128&gt;
0x0ffaeb74 &lt;shared_free+32&gt;:    li      r9,0
0x0ffaeb78 &lt;shared_free+36&gt;:    lwz     r0,36(r1)
0x0ffaeb7c &lt;shared_free+40&gt;:    mr      r3,r9
0x0ffaeb80 &lt;shared_free+44&gt;:    addi    r1,r1,32
0x0ffaeb84 &lt;shared_free+48&gt;:    mtlr    r0
0x0ffaeb88 &lt;shared_free+52&gt;:    blr
    </screen>
  </chapter>
  <chapter id="credits">
    <title>Credits and notes on this document</title>
    <para>
      This document created: 10 Jan 2002, 13 Jan 2002. Junichi Uekawa (<email>dancer@debian.org</email>).
      Revised to be up-to-date on 17 Mar 2002.
      31 Mar 2002, merged suggestions from David Schmitt.
      Translation to DocBook SGML done on 8 April 2002.
      Major spell-checking and review was done on 11 April 2002.
      Reorganisation of some text was done on 14 April 2002.
      Added more real-ish examples on what files go where, on 9 May 2002.
      Overview of usage of term SONAME was done on 12 May 2002, and they
      were corrected.
      Some more examples were added on 20 May 2002, and some language fixing 
      was done on 25 May 2002.
      Added some notes on shlibs.local file at the end on 23 June 2002, because
      this document was missing that large portion.
      Added notes on libvorbis breakage on 8 Aug 2002, and start adding symbol versioning information (not really complete.)
      Notes on binary compatibility and shared library versioning are updated.
      Rewording on confusing binarycompat section cleared up slightly, 9 Aug 2002.
      Updates on versioned symbols, 13 Feb 2003.
    </para>
    <para>
      More documentation on versioned symbols and dlopening problems, 
      summarising what was discussed over libssl0.9.6/0.9.7 discussion, on 
      17 Mar 2003.
      Also, on that occasion, a read-through and general improvements was done over the
      text.
    </para>
    <para>
      25 Jun 2003; Received fixes on some text from John Belmonte.
    </para>
    <para>
      28 Sep 2003; added URL from what was said on IRC with regards to symbol versioning.
    </para>
    <para>
      18 Apr 2004; updates on testing/unstable migration problem.
    </para>
    <para>
      1 June 2004: update after vorlon's talk on dependency hells,
      a howto on making a shared library with versioned symbol.
    </para>
    <para>
      14 Jul 2004: Quickly added a -rpath chapter, since nothing
      was said in libpkg-guide, and DWN had something to say.
    </para>
    <para>
      5 Feb 2005: translated to docbook XML format
    </para>
    <para>
      28 May 2005: added sed snippet to obtain shared library package name.
    </para>
    <para>
      16 June 2005: Moved around text for how shared library should be named,

      from what files are installed. It was confusing.
    </para>
    <para>
      17 June 2005: spelling mistake fix reported by Lior Kaplan.
    </para>
    <para>
      25 June 2005: added reference to example of when SONAME doesn't change,
      and a &gt;= relationship is required.
    </para>
    <para>
      8 Jul 2005: addition of reference to how shared libraries get 
      loaded, and other details.
    </para>
    <para>
      15 Jul 2005: Remove the part referencing about dlopen module 
      and -DEV dependency.
      -DEV dependency does not really help with dlopen modules with
      mixed symbols.
      The problems with dlopening is discussed in its own chapter.
    </para>
    <para>
      12 Nov 2005: fix missing space, thanks to Nico Golde.
    </para>
    <para>
      27 Nov 2005: typo fixes and grammar corrections, 'there is no dh_shlibs command, but dh_makeshlibs', thanks to Florian Ernst.
      Add reference to writing DSO's document from Ulrich Drepper.
    </para>
    <para>
      3 Dec 2005: "Table 8.1, slang-utf8 reference URL was not clickable", 
      "Table 9.1 Changes and effects has duplicate row about Adding a function"
      reported by 'Davide'
    </para>
    <para>
      5 Mar 2006: reformatting to make a PDF version readable.
    </para>
    <para>
      20 May 2006: reflected result of discussing the document over
      with Josselin Mouette, over his presentation on shared libraries
      at Debconf in Mexico.  Majorly reorganised text around, so that the chapters are in a 
      more meaningful order.
      Unify example shared library name to "libfoo" and "libbar".
    </para>
    <para>
      31 Jul 2006: fix typo.
    </para>
    <para>	
      Distributed under the terms of GPL version 2 or later.
    </para>
  </chapter>
</book>
<!--  LocalWords:  objdump libtool versioning Josselin Mouette libfoo libbar
 -->
<!--  LocalWords:  GPL PDF URL Ulrich Drepper dlopen dlopening docbook SONAME
 -->
<!--  LocalWords:  versioned prelink unversioned installable namespace regex
 -->
