</p>
</sect>
</chapt>
+
<chapt>
<heading>The Debian Archive</heading>
<p>
ignored there; it is conventional to put a single space
after the colon. For example, a field might be:
<example>
- Package: libc6
+Package: libc6
</example>
the field name is <tt>Package</tt> and the field value
<tt>libc6</tt>.
<p>If a version of the package is already
installed, call
<example>
- <var>old-prerm</var> upgrade <var>new-version</var>
+<var>old-prerm</var> upgrade <var>new-version</var>
</example></p>
</item>
<item>
If the script runs but exits with a non-zero
exit status, <prgn>dpkg</prgn> will attempt:
<example>
- <var>new-prerm</var> failed-upgrade <var>old-version</var>
+<var>new-prerm</var> failed-upgrade <var>old-version</var>
</example>
Error unwind, for both the above cases:
<example>
- <var>old-postinst</var> abort-upgrade <var>new-version</var>
+<var>old-postinst</var> abort-upgrade <var>new-version</var>
</example>
</p>
</item>
package and <tt>--auto-deconfigure</tt> is
specified, call, for each such package:
<example>
- <var>deconfigured's-prerm</var> deconfigure \
- in-favour <var>package-being-installed</var> <var>version</var> \
- removing <var>conflicting-package</var> <var>version</var>
+<var>deconfigured's-prerm</var> deconfigure \
+ in-favour <var>package-being-installed</var> <var>version</var> \
+ removing <var>conflicting-package</var> <var>version</var>
</example>
Error unwind:
<example>
- <var>deconfigured's-postinst</var> abort-deconfigure \
- in-favour <var>package-being-installed-but-failed</var> <var>version</var> \
- removing <var>conflicting-package</var> <var>version</var>
+<var>deconfigured's-postinst</var> abort-deconfigure \
+ in-favour <var>package-being-installed-but-failed</var> <var>version</var> \
+ removing <var>conflicting-package</var> <var>version</var>
</example>
The deconfigured packages are marked as
requiring configuration, so that if
<item>
<p>To prepare for removal of the conflicting package, call:
<example>
- <var>conflictor's-prerm</var> remove in-favour <var>package</var> <var>new-version</var>
+<var>conflictor's-prerm</var> remove \
+ in-favour <var>package</var> <var>new-version</var>
</example>
Error unwind:
<example>
- <var>conflictor's-postinst</var> abort-remove \
- in-favour <var>package</var> <var>new-version</var>
+<var>conflictor's-postinst</var> abort-remove \
+ in-favour <var>package</var> <var>new-version</var>
</example>
</p>
</item>
<item>
<p>If the package is being upgraded, call:
<example>
- <var>new-preinst</var> upgrade <var>old-version</var>
+<var>new-preinst</var> upgrade <var>old-version</var>
</example></p>
</item>
<item>
files from a previous version installed (i.e., it
is in the `configuration files only' state):
<example>
- <var>new-preinst</var> install <var>old-version</var>
+<var>new-preinst</var> install <var>old-version</var>
</example></p>
<item>
<p>Otherwise (i.e., the package was completely purged):
<example>
- <var>new-preinst</var> install
+<var>new-preinst</var> install
</example>
Error unwind actions, respectively:
<example>
- <var>new-postrm</var> abort-upgrade <var>old-version</var>
- <var>new-postrm</var> abort-install <var>old-version</var>
- <var>new-postrm</var> abort-install
+<var>new-postrm</var> abort-upgrade <var>old-version</var>
+<var>new-postrm</var> abort-install <var>old-version</var>
+<var>new-postrm</var> abort-install
</example>
</p>
</item>
<item>
<p>If the package is being upgraded, call
<example>
- <var>old-postrm</var> upgrade <var>new-version</var>
+<var>old-postrm</var> upgrade <var>new-version</var>
</example></p>
</item>
<item>
<p>If this fails, <prgn>dpkg</prgn> will attempt:
<example>
- <var>new-postrm</var> failed-upgrade <var>old-version</var>
+<var>new-postrm</var> failed-upgrade <var>old-version</var>
</example>
Error unwind, for both cases:
<example>
- <var>old-preinst</var> abort-upgrade <var>new-version</var>
+<var>old-preinst</var> abort-upgrade <var>new-version</var>
</example>
</p>
</item>
<item>
<p><prgn>dpkg</prgn> calls:
<example>
- <var>disappearer's-postrm</var> disappear \
- <var>overwriter</var> <var>overwriter-version</var>
+<var>disappearer's-postrm</var> disappear \
+ <var>overwriter</var> <var>overwriter-version</var>
</example>
</p>
</item>
--install</tt>, or with <tt>--configure</tt>), we first
update any <tt>conffile</tt>s and then call:
<example>
- <var>postinst</var> configure <var>most-recently-configured-version</var>
+<var>postinst</var> configure <var>most-recently-configured-version</var>
</example>
</p>
<item>
<p>
<example>
- <var>prerm</var> remove
+<var>prerm</var> remove
</example>
</p>
</item>
</p>
</item>
<item>
- <p><example>
- <var>postrm</var> remove
- </example></p>
+ <p>
+ <example>
+<var>postrm</var> remove
+ </example>
+ </p>
</item>
<item>
<p>
<tt>.dpkg-{old,new,tmp}</tt>, etc.) are removed.</p>
</item>
<item>
- <p><example>
- <var>postrm</var> purge
- </example></p>
+ <p>
+ <example>
+<var>postrm</var> purge
+ </example>
+ </p>
</item>
<item>
<p>The package's file list is removed.</p>
<p>
For example, a list of dependencies might appear as:
<example>
- Package: mutt
- Version: 1.3.17-1
- Depends: libc6 (>= 2.2.1), exim | mail-transport-agent
+Package: mutt
+Version: 1.3.17-1
+Depends: libc6 (>= 2.2.1), exim | mail-transport-agent
</example>
</p>
<p>
For example:
<example>
- Source: glibc
- Build-Depends-Indep: texinfo
- Build-Depends: kernel-headers-2.2.10 [!hurd-i386],
- hurd-dev [hurd-i386], gnumach-dev [hurd-i386]
+Source: glibc
+Build-Depends-Indep: texinfo
+Build-Depends: kernel-headers-2.2.10 [!hurd-i386],
+hurd-dev [hurd-i386], gnumach-dev [hurd-i386]
</example>
</p>
</sect>
packages which provide it. This is so that, for example,
supposing we have
<example>
- Package: foo
- Depends: bar
+Package: foo
+Depends: bar
</example>
and someone else releases an enhanced version of the
<tt>bar</tt> package (for example, a non-US variant), they
can say:
<example>
- Package: bar-plus
- Provides: bar
+Package: bar-plus
+Provides: bar
</example>
and the <tt>bar-plus</tt> package will now also satisfy the
dependency for the <tt>foo</tt> package.
</p>
<p>
- Any package installing shared libraries in a directory that is
- listed in <tt>/etc/ld.so.conf</tt> or in one of the default
- library directories of the dynamic linker (currently, these
- are <tt>/usr/lib</tt> and <tt>/lib</tt>) must call
- <prgn>ldconfig</prgn> in its <prgn>postinst</prgn> script if
- and only if the first argument is `configure'. However, it is
- important not to call <prgn>ldconfig</prgn> in the postrm or
- preinst scripts in the case where the package is being
- upgraded (see <ref id="unpackphase">), as
- <prgn>ldconfig</prgn> will see the temporary names that
- <prgn>dpkg</prgn> uses for the files while it is installing
- them and will make the shared library links point to them,
- just before <prgn>dpkg</prgn> continues the installation and
- removes the links!
+ Any package installing shared libraries in one of the default
+ library directories of the dynamic linker (which are currently
+ <tt>/usr/lib</tt> and <tt>/lib</tt>) or a directory that is
+ listed in <tt>/etc/ld.so.conf</tt>
+ <footnote>
+ <p>
+ These are currently
+ <list>
+ <item><p>/usr/X11R6/lib/Xaw3d</p></item>
+ <item><p>/usr/local/lib</p></item>
+ <item><p>/usr/lib/libc5-compat</p></item>
+ <item><p>/lib/libc5-compat</p></item>
+ <item><p>/usr/X11R6/lib</p></item>
+ </list>
+ </p>
+ </footnote>
+ must call <prgn>ldconfig</prgn> in its <prgn>postinst</prgn>
+ script if and only if the first argument is <tt>configure</tt>
+ and should call it in the <prgn>postrm</prgn> script if the
+ first argument is <tt>remove</tt>.
</p>
- <sect id="shlibs"><heading>The <tt>shlibs</tt> File Format
- </heading>
+ <p>
+ However, <prgn>postrm</prgn> and <prgn>preinst</prgn> scripts
+ <em>must not</em> call <prgn>ldconfig</prgn> in the case where
+ the package is being upgraded (see <ref id="unpackphase"> for
+ details), as <prgn>ldconfig</prgn> will see the temporary
+ names that <prgn>dpkg</prgn> uses for the files while it is
+ installing them and will make the shared library links point
+ to them, just before <prgn>dpkg</prgn> continues the
+ installation and renames the temporary files!
+ </p>
- <p>
- This file is for use by <prgn>dpkg-shlibdeps</prgn> and is
- required when your package provides shared libraries.
- </p>
+ <sect>
+ <heading>Handling shared library dependencies - the
+ <tt>shlibs</tt> system</heading>
+
+ <p>
+ If a package contains a binary or library which links to a
+ shared library, we must ensure that when the package is
+ installed on the system, all of the libraries needed are
+ also installed. This requirement led to the creation of the
+ <tt>shlibs</tt> system, which is very simple in its design:
+ any package which <em>provides</em> a shared library also
+ provides information on the package dependencies required to
+ ensure the presence of this library, and any package which
+ <em>uses</em> a shared library uses this information to
+ determine the dependencies it requires. The files which
+ contain the mapping from shared libraries to the necessary
+ dependency information are called <tt>shlibs</tt> files.
+ </p>
+
+ <p>
+ Thus, when a package is built which contains any shared
+ libraries, it must provide a <tt>shlibs</tt> file for other
+ packages to use, and when a package is built which contains
+ any shared libraries or compiled binaries, it must run
+ <prgn>dpkg-shlibdeps</prgn> on these to determine the
+ libraries used and hence the dependencies needed by this
+ package.
+ <footnote>
+ <p>
+ In the past, the shared libraries linked to were
+ determined by calling <prgn>ldd</prgn>, but now
+ <prgn>objdump</prgn> to do this. The only change this
+ makes to package building is that
+ <prgn>dpkg-shlibdeps</prgn> must also be run on shared
+ libraries, whereas in the past this was unnecessary.
+ The rest of this footnote explains the advantage that
+ this method gives.
+ </p>
- <p>
- Each line is of the form:
- <example>
- <var>library-name</var> <var>version-or-soname</var> <var>dependencies ...</var>
- </example>
- </p>
+ <p>
+ We say that a binary <tt>foo</tt> <em>directly</em> uses
+ a library <tt>libbar</tt> if it is explicitly linked
+ with that library (that is, it uses the flag
+ <tt>-lbar</tt> during the linking stage). Other
+ libraries that are needed by <tt>libbar</tt> are linked
+ <em>indirectly</em> to <tt>foo</tt>, and the dynamic
+ linker will load them automatically when it loads
+ <tt>libbar</tt>. A package should needs to depend on
+ the libraries it directly uses, and the dependencies for
+ those libraries should automatically pull in the other
+ libraries.
+ </p>
- <p>
- <var>library-name</var> is the name of the shared library,
- for example <tt>libc5</tt>.
- </p>
+ <p>
+ Unfortunately, the <prgn>ldd</prgn> program shows both
+ the directly and indirectly used libraries, meaning that
+ the dependencies determined included both direct and
+ indirect dependencies. The use of <prgn>objdump</prgn>
+ avoids this problem by determining only the directly
+ used libraries.
+ </p>
- <p>
- <var>version-or-soname</var> is the soname of the library -
- i.e., the thing that must exactly match for the library to be
- recognized by <prgn>ld.so</prgn>. Usually this is the major
- version number of the library.
+ <p>
+ A good example of where this helps is the following. We
+ could update <tt>libimlib</tt> with a new version that
+ supports a new graphics format called dgf (but retaining
+ the same major version number). If we used the old
+ <prgn>ldd</prgn> method, every package that uses
+ <tt>libimlib</tt> would need to be recompiled so it
+ would also depend on <tt>libdgf</tt> or it wouldn't run
+ due to missing symbols. However with the new system,
+ packages using <tt>libimlib</tt> can rely on
+ <tt>libimlib</tt> itself having the dependency on
+ <tt>libdgf</tt> and so they would not need rebuilding.
+ </p>
+ </footnote>
</p>
<p>
- <var>dependencies</var> has the same syntax as a dependency
- field in a binary package control file. It should give
- details of which package(s) are required to satisfy a binary
- built against the version of the library contained in the
- package. See <ref id="depsyntax">.
+ In the following sections, we will first describe where the
+ various <tt>shlibs</tt> files are to be found, then how to
+ use <prgn>dpkg-shlibdeps</prgn>, and finally the
+ <tt>shlibs</tt> file format and how to create them if your
+ package contains a shared library.
</p>
+ </sect>
+
+ <sect><heading>The <tt>shlibs</tt> files present on the system
+ </heading>
<p>
- For example, if the package <tt>foo</tt> contains
- <tt>libfoo.so.1.2.3</tt>, where the soname of the library is
- <tt>libfoo.so.1</tt>, and the first version of the package
- which contained a minor number of at least <tt>2.3</tt> was
- <var>1.2.3-1</var>, then the package's <var>shlibs</var>
- could say:
- <example>
- libfoo 1 foo (>= 1.2.3-1)
- </example>
+ There are several places where <tt>shlibs</tt> files are
+ found. The following list gives them in the order in which
+ they are read by <prgn>dpkg-shlibdeps</prgn>. (The first
+ one which gives the required information is used.)
</p>
<p>
- The version-specific dependency is to avoid warnings from
- <prgn>ld.so</prgn> about using older shared libraries with
- newer binaries.</p>
- </sect>
-
- <sect><heading>Further Technical information on
- <tt>shlibs</tt></heading>
-
- <sect1><heading><em>What</em> are the <tt>shlibs</tt> files?
- </heading>
-
- <p>
- The <tt>debian/shlibs</tt> file provides a way of checking
- for shared library dependencies on packaged binaries.
- They are intended to be used by package maintainers to
- make their lives easier.
- </p>
-
- <p>
- Other <tt>shlibs</tt> files that exist on a Debian system are
- <list>
- <item> <p><tt>/etc/dpkg/shlibs.default</tt></p></item>
- <item> <p><tt>/etc/dpkg/shlibs.override</tt></p></item>
- <item> <p><tt>/var/lib/dpkg/info/*.shlibs</tt></p></item>
- <item> <p><tt>debian/shlibs.local</tt></p></item>
- </list>
- These files are used by <prgn>dpkg-shlibdeps</prgn> when
- creating a binary package.</p>
- </sect1>
-
- <sect1><heading><em>How</em> does <prgn>dpkg-shlibdeps</prgn>
- work?
- </heading>
- <p>
- <prgn>dpkg-shlibdeps</prgn>
- determines the shared libraries directly
- <footnote>
+ <taglist>
+ <tag><tt>debian/shlibs.local</tt></tag>
+ <item>
<p>
- It used to do this by calling <prgn>ldd</prgn>, but it
- now calls <prgn>objdump</prgn> to do this. This
- requires a couple of changes in the way that packages
- are built.
+ This lists overrides for this package. Its use is
+ described below (see <ref id="shlibslocal">).
</p>
+ </item>
+
+ <tag><tt>/etc/dpkg/shlibs.override</tt></tag>
+ <item>
<p>
- A binary <tt>foo</tt> directly uses a library
- <tt>libbar</tt> if it is linked with that
- library. Other libraries that are needed by
- <tt>libbar</tt> are linked indirectly to <tt>foo</tt>,
- and the dynamic linker will load them automatically
- when it loads <tt>libbar</tt>. Running<prgn>ldd</prgn>
- lists all of the libraries used, both directly and
- indirectly; but <prgn>objdump</prgn> only lists the
- directly linked libraries. A package only needs to
- depend on the libraries it is directly linked to,
- since the dependencies for those libraries should
- automatically pull in the other libraries.
+ This lists global overrides. This list is normally
+ empty. It is maintained by the local system
+ administrator.
</p>
+ </item>
+
+ <tag><tt>DEBIAN/shlibs</tt> files in the `build directory'</tag>
+ <item>
<p>
- This change does mean a change in the way packages are
- build though: currently <prgn>dpkg-shlibdeps</prgn> is
- only run on binaries. But since we will now rely on the
- libraries depending on the libraries they themselves
- need, the packages containing those libraries will
- need to run <prgn>dpkg-shlibdeps</prgn> on the
- libraries.
+ When packages are being built, any
+ <tt>debian/shlibs</tt> files are copied into the
+ control file area of the temporary build directory and
+ given the name <tt>shlibs</tt>. These files give
+ details of any shared libraries included in the
+ package.
+ <footnote>
+ <p>
+ An example may help here. Let us say that the
+ source package <tt>foo</tt> generates two binary
+ packages, <tt>libfoo2</tt> and
+ <tt>foo-runtime</tt>. When building the binary
+ packages, the two packages are created in the
+ directories <tt>debian/libfoo2</tt> and
+ <tt>debian/foo-runtime</tt> respectively.
+ (<tt>debian/tmp</tt> could be used instead of one
+ of these.) Since <tt>libfoo2</tt> provides the
+ <tt>libfoo</tt> shared library, it will require a
+ <tt>shlibs</tt> file, which will be installed in
+ <tt>debian/libfoo2/DEBIAN/shlibs</tt>, eventually
+ to become
+ <tt>/var/lib/dpkg/info/libfoo2.shlibs</tt>. Then
+ when <prgn>dpkg-shlibdeps</prgn> is run on the
+ executable
+ <tt>debian/foo-runtime/usr/bin/foo-prog</tt>, it
+ will examine the
+ <tt>debian/libfoo2/DEBIAN/shlibs</tt> file to
+ determine whether <tt>foo-prog</tt>'s library
+ dependencies are satisfied by any of the libraries
+ provided by <tt>libfoo2</tt>. For this reason,
+ <prgn>dpkg-shlibdeps</prgn> must only be run once
+ all of the individual binary packages'
+ <tt>shlibs</tt> files have been installed into the
+ build directory.
+ </p>
+ </footnote>
</p>
+ </item>
+
+ <tag><tt>/var/lib/dpkg/info/*.shlibs</tt></tag>
+ <item>
<p>
- A good example where this would help us is the current
- mess with multiple version of the <tt>mesa</tt>
- library. With the <prgn>ldd</prgn>-based system, every
- package that uses <tt>mesa</tt> needs to add a
- dependency on <tt>svgalib|svgalib-dummy</tt> in order
- to handle the glide <tt>mesa</tt> variant. With an
- <prgn>objdump</prgn>-based system this isn't necessary
- anymore and would have saved everyone a lot of work.
+ These are the <tt>shlibs</tt> files corresponding to
+ all of the packages installed on the system, and are
+ maintained by the relevant package maintainers.
</p>
+ </item>
+
+ <tag><tt>/etc/dpkg/shlibs.default</tt></tag>
+ <item>
<p>
- Another example: we could update <tt>libimlib</tt>
- with a new version that supports a new graphics format
- called dgf. If we use the old <prgn>ldd</prgn> method,
- every package that uses <tt>libimlib</tt> would need
- to be recompiled so it would also depend on
- <tt>libdgf</tt> or it wouldn't run due to missing
- symbols. However with the new system, packages using
- <tt>libimlib</tt> can rely on <tt>libimlib</tt> itself
- having the dependency on <tt>libdgf</tt> and wouldn't
- need to be updated.
+ This file lists any shared libraries whose packages
+ have failed to provide correct <tt>shlibs</tt> files.
+ It was used when the <tt>shlibs</tt> setup was first
+ introduced, but it is now normally empty. It is
+ maintained by the <tt>dpkg</tt> maintainer.
</p>
- </footnote>
- used by the compiled binaries and libraries passed through
- on its command line.
- </p>
+ </item>
+ </taglist>
+ </p>
+ </sect>
- <p>
- For each shared library linked to,
- <prgn>dpkg-shlibdeps</prgn> needs to know
- <list compact="compact">
- <item><p>the package containing the library, and</p></item>
- <item><p>the library version number,</p></item>
- </list>
- and it scans the following files in this order:
- <enumlist compact="compact">
- <item><p><tt>debian/shlibs.local</tt></p></item>
- <item><p><tt>/etc/dpkg/shlibs.override</tt></p></item>
- <item><p><tt>/var/lib/dpkg/info/*.shlibs</tt></p></item>
- <item><p><tt>/etc/dpkg/shlibs.default</tt></p></item>
- </enumlist>
- </p>
- </sect1>
+ <sect>
+ <heading>How to use <prgn>dpkg-shlibdeps</prgn> and the
+ <tt>shlibs</tt> files</heading>
- <sect1><heading><em>Who</em> maintains the various
- <tt>shlibs</tt> files?
- </heading>
+ <p>
+ Put a call to <prgn>dpkg-shlibdeps</prgn> into your
+ <tt>debian/rules</tt> file. If your package contains only
+ compiled binaries and libraries (but no scripts), you can
+ use a command such as:
+ <example>
+dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/* \
+ debian/tmp/usr/lib/*
+ </example>
+ Otherwise, you will need to explicitly list the compiled
+ binaries and libraries.
+ <footnote>
+ <p>
+ If you are using <tt>debhelper</tt>, the
+ <prgn>dh_shlibdeps</prgn> program will do this work for
+ you. It will also correctly handle multi-binary
+ packages.
+ </p>
+ </footnote>
+ </p>
- <p>
- <list compact="compact">
- <item>
- <p><tt>/etc/dpkg/shlibs.default</tt> - the maintainer
- of dpkg</p>
- </item>
- <item>
- <p>
- <tt>/var/lib/dpkg/info/<var>package</var>.shlibs</tt>
- - the maintainer of each package</p>
- </item>
- <item>
- <p>
- <tt>/etc/dpkg/shlibs.override</tt> - the local
- system administrator</p>
- </item>
- <item>
- <p><tt>debian/shlibs.local</tt> - the maintainer of
- the package
- </p>
- </item>
- </list>
- The <tt>shlibs.default</tt> file is managed by
- <prgn>dpkg</prgn>. The entries in <tt>shlibs.default</tt>
- that are provided by <prgn>dpkg</prgn> are just there to
- fix things until the shared library packages all have
- <tt>shlibs</tt> files.
- </p>
- </sect1>
+ <p>
+ This command puts the dependency information into the
+ <tt>debian/substvars</tt> file, which is then used by
+ <prgn>dpkg-gencontrol</prgn>. You will need to place a
+ <tt>${shlib:Depends}</tt> variable in the <tt>Depends</tt>
+ field in the control file for this to work.
+ </p>
- <sect1><heading><em>How</em> to use <prgn>dpkg-shlibdeps</prgn> and
- the <tt>shlibs</tt> files
- </heading>
+ <p>
+ If <prgn>dpkg-shlibdeps</prgn> doesn't complain, you're
+ done. If it does complain you might need to create your own
+ <tt>debian/shlibs.local</tt> file, as explained below (see
+ <ref id="shlibslocal">).
+ </p>
+
+ <p>
+ If you have multiple binary packages, you will need to call
+ <prgn>dpkg-shlibdeps</prgn> on each one which contains
+ compiled libraries or binaries. In such a case, you will
+ need to use the <tt>-T</tt> option to the <tt>dpkg</tt>
+ utilities to specify a different <tt>substvars</tt> file.
+ For more details on this and other options, see <manref
+ name="dpkg-shlibdeps" section="1">.
+ </p>
+ </sect>
+
+ <sect id="shlibs"><heading>The <tt>shlibs</tt> File Format
+ </heading>
+
+ <p>
+ Each <tt>shlibs</tt> file has the same format. Lines
+ beginning with <tt>#</tt> are considered to be commments and
+ are ignored. Each line is of the form:
+ <example>
+<var>library-name</var> <var>soname-version-number</var> <var>dependencies ...</var>
+ </example>
+ </p>
+
+ <p>
+ We will explain this by reference to the example of the
+ <tt>zlib1g</tt> package, which (at the time of writing)
+ installs the shared library <tt>/usr/lib/libz.so.1.1.3</tt>.
+ </p>
- <sect2><heading>If your package doesn't provide a shared
- library
- </heading>
+ <p>
+ <var>library-name</var> is the name of the shared library,
+ in this case <tt>libz</tt>. (This must match the name part
+ of the soname, see below.)
+ </p>
+ <p>
+ <var>soname-version-number</var> is the version part of the
+ soname of the library. The soname is the thing that must
+ exactly match for the library to be recognized by the
+ dynamic linker, and is usually of the form
+ <tt><var>name</var>.so.<var>major-version</var></tt>, in our
+ example, <tt>libz.so.1</tt>.
+ <footnote>
<p>
- Put a call to <prgn>dpkg-shlibdeps</prgn> into your
- <tt>debian/rules</tt> file. If your package contains
- only binaries (e.g. no scripts) use:
+ This can be determined using the command
<example>
- dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/*
+objdump -p /usr/lib/libz.so.1.1.3 | grep SONAME
</example>
- If <prgn>dpkg-shlibdeps</prgn> doesn't complain, you're
- done. If it does complain you might need to create your
- own <tt>debian/shlibs.local</tt> file.</p>
- </sect2>
+ </p>
+ </footnote>
+ The version part is the part which comes after
+ <tt>.so.</tt>, so in our case, it is <tt>1</tt>.
+ </p>
+
+ <p>
+ <var>dependencies</var> has the same syntax as a dependency
+ field in a binary package control file. It should give
+ details of which packages are required to satisfy a binary
+ built against the version of the library contained in the
+ package. See <ref id="depsyntax"> for details.
+ </p>
+
+ <p>
+ In our example, if the first version of the <tt>zlib1g</tt>
+ package which contained a minor number of at least
+ <tt>1.3</tt> was <var>1:1.1.3-1</var>, then the
+ <tt>shlibs</tt> entry for this library could say:
+ <example>
+libz 1 zlib1g (>= 1:1.1.3)
+ </example>
+ The version-specific dependency is to avoid warnings from
+ the dynamic linker about using older shared libraries with
+ newer binaries.
+ </p>
+ </sect>
- <sect2><heading>If your package provides a shared library
- </heading>
+ <sect>
+ <heading>Providing a <tt>shlibs</tt> file</heading>
+ <p>
+ If your package provides a shared library, you should create
+ a <tt>shlibs</tt> file following the format described above.
+ It is usual to call this file <tt>debian/shlibs</tt> (but if
+ you have multiple binary packages, you might want to call it
+ <tt>debian/shlibs.<var>package</var></tt> instead). Then
+ let <tt>debian/rules</tt> install it in the control area:
+ <example>
+install -m644 debian/shlibs debian/tmp/DEBIAN
+ </example>
+ or, in the case of a multi-binary package:
+ <example>
+install -m644 debian/shlibs.<var>package</var> debian/<var>package</var>/DEBIAN/shlibs
+ </example>
+ An alternative way of doing this is to create the
+ <tt>shlibs</tt> file in the control area directly from
+ <tt>debian/rules</tt> without using a <tt>debian/shlibs</tt>
+ file at all,
+ <footnote>
<p>
- Create a <tt>debian/shlibs</tt> file and let
- <tt>debian/rules</tt> install it in the control area:
- <example>
- install -m644 debian/shlibs debian/tmp/DEBIAN
- </example>
- If your package contains additional binaries see above.
+ This is what <prgn>dh_makeshlibs</prgn> in the
+ <tt>debhelper</tt> suite does.
</p>
- </sect2>
- </sect1>
+ </footnote>
+ since the <tt>debian/shlibs</tt> file itself is ignored by
+ <prgn>dpkg-shlibdeps</prgn>.
+ </p>
- <sect1><heading><em>How</em> to write
- <tt>debian/shlibs.local</tt>
- </heading>
+ <p>
+ As <prgn>dpkg-shlibdeps</prgn> reads the
+ <tt>DEBIAN/shlibs</tt> files in all of the binary packages
+ being built from this source package, all of the
+ <tt>DEBIAN/shlibs</tt> files should be installed before
+ <prgn>dpkg-shlibdeps</prgn> is called on any of the binary
+ packages.
+ </p>
+ </sect>
- <p>
- This file is intended only as a <em>temporary</em> fix if
- your binaries depend on a library which doesn't provide
- its own <tt>/var/lib/dpkg/info/*.shlibs</tt> file yet.
- </p>
+ <sect id="shlibslocal">
+ <heading>Writing the <tt>debian/shlibs.local</tt> file</heading>
- <p>
- Let's assume you are packaging a binary <tt>foo</tt>. Your
- output in building the package might look like this.
- <example>
- $ ldd foo
- libbar.so.1 => /usr/X11R6/lib/libbar.so.1.0 (0x4001e000)
- libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x4002c000)
- libc.so.6 => /lib/libc.so.6 (0x40114000)
- /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
- </example>
- And when you ran <prgn>dpkg-shlibdeps</prgn>
- <example>
- $ dpkg-shlibdeps -O foo
- dpkg-shlibdeps: warning: unable to find dependency information for shared library libbar
- (soname 1, path /usr/X11R6/lib/libbar.so.1.0, dependency field Depends)
- shlibs:Depends=libc6 (>= 2.2.1), xlibs (>= 4.0.1-11)
- </example>
- The <prgn>foo</prgn> binary depends on the
- <prgn>libbar</prgn> shared library, but no package seems
- to provide a <tt>*.shlibs</tt> file in
- <tt>/var/lib/dpkg/info/</tt>. Let's determine the package
- responsible:
- </p>
+ <p>
+ This file is intended only as a <em>temporary</em> fix if
+ your binaries or libraries depend on a library whose package
+ does not yet provide a correct <tt>shlibs</tt> file.
+ </p>
- <p>
- <example>
- $ dpkg -S /usr/X11R6/lib/libbar.so.1.0
- bar1: /usr/X11R6/lib/libbar.so.1.0
- $ dpkg -s bar1 | grep Version
- Version: 1.0-1
- </example>
- This tells us that the <prgn>bar1</prgn> package, version
- 1.0-1 is the one we are using. Now we can create our own
- <tt>debian/shlibs.local</tt> to temporarily fix the above
- problem. Include the following line into your
- <tt>debian/shlibs.local</tt> file.
- <example>
- libbar 1 bar1 (>= 1.0-1)
- </example>
- Now your package build should work. As soon as the
- maintainer of <prgn>libbar1</prgn> provides a
- <tt>shlibs</tt> file, you can remove your
- <tt>debian/shlibs.local</tt> file.
- </p>
- </sect1>
+ <p>
+ We will assume that you are trying to package a binary
+ <tt>foo</tt>. When you try running
+ <prgn>dpkg-shlibdeps</prgn> you get the following error
+ message (<tt>-O</tt> displays the dependency information on
+ <tt>stdout</tt> instead of writing it to
+ <tt>debian/substvars</tt>, and the lines have been wrapped
+ for ease of reading):
+ <example>
+$ dpkg-shlibdeps -O debian/tmp/usr/bin/foo
+dpkg-shlibdeps: warning: unable to find dependency
+ information for shared library libbar (soname 1,
+ path /usr/lib/libbar.so.1, dependency field Depends)
+shlibs:Depends=libc6 (>= 2.2.2-2)
+ </example>
+ You can then run <prgn>ldd</prgn> on the binary to find the
+ full location of the library concerned:
+ <example>
+$ ldd foo
+libbar.so.1 => /usr/lib/libbar.so.1 (0x4001e000)
+libc.so.6 => /lib/libc.so.6 (0x40032000)
+/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
+ </example>
+ So the <prgn>foo</prgn> binary depends on the
+ <prgn>libbar</prgn> shared library, but no package seems to
+ provide a <tt>*.shlibs</tt> file handling
+ <tt>libbar.so.1</tt> in <tt>/var/lib/dpkg/info/</tt>. Let's
+ determine the package responsible:
+ <example>
+$ dpkg -S /usr/lib/libbar.so.1
+bar1: /usr/lib/libbar.so.1
+$ dpkg -s bar1 | grep Version
+Version: 1.0-1
+ </example>
+ This tells us that the <tt>bar1</tt> package, version 1.0-1,
+ is the one we are using. Now we can file a bug against the
+ <tt>bar1</tt> package and create our own
+ <tt>debian/shlibs.local</tt> to locally fix the problem.
+ Including the following line into your
+ <tt>debian/shlibs.local</tt> file:
+ <example>
+libbar 1 bar1 (>= 1.0-1)
+ </example>
+ should allow the package build to work.
+ </p>
+
+ <p>
+ As soon as the maintainer of <tt>bar1</tt> provides a
+ correct <tt>shlibs</tt> file, you should remove this line
+ from your <tt>debian/shlibs.local</tt> file. (You should
+ probably also then have a versioned <tt>Build-Depends</tt>
+ on <tt>bar1</tt> to help ensure that others do not have the
+ same problem building your package.)
+ </p>
</sect>
</chapt>
<chapt><heading>The Operating System</heading>
-
<sect>
<heading>File system hierarchy</heading>
<p>
For example, the <prgn>emacs</prgn> package will contain
<example>
- mkdir -p /usr/local/lib/emacs/site-lisp || true
+mkdir -p /usr/local/lib/emacs/site-lisp || true
</example>
in the <tt>postinst</tt> script, and
<example>
- rmdir /usr/local/lib/emacs/site-lisp || true
- rmdir /usr/local/lib/emacs || true
+rmdir /usr/local/lib/emacs/site-lisp || true
+rmdir /usr/local/lib/emacs || true
</example>
in the <tt>prerm</tt> script.</p>
<prgn>bind</prgn> would have a lower number than the
script that starts <prgn>inn</prgn> so that it runs first:
<example>
- /etc/rc2.d/S17bind
- /etc/rc2.d/S70inn
+/etc/rc2.d/S17bind
+/etc/rc2.d/S70inn
</example>
</p>
</sect1>
should include a <tt>test</tt> statement at the top of the
script, like this:
<example>
- test -f <var>program-executed-later-in-script</var> || exit 0
+test -f <var>program-executed-later-in-script</var> || exit 0
</example></p>
<p>
To get the default behavior for your package, put in your
<tt>postinst</tt> script
<example>
- update-rc.d <var>package</var> defaults >/dev/null
+update-rc.d <var>package</var> defaults >/dev/null
</example>
and in your <tt>postrm</tt>
<example>
- if [ purge = "$1" ]; then
- update-rc.d <var>package</var> remove >/dev/null
- fi
+if [ purge = "$1" ]; then
+ update-rc.d <var>package</var> remove >/dev/null
+fi
</example></p>
<p>
<p>
<example>
- #!/bin/sh
- #
- # Original version by Robert Leslie
- # <rob@mars.org>, edited by iwj and cs
-
- test -x /usr/sbin/named || exit 0
-
- # Source defaults file.
- PARAMS=''
- if [ -f /etc/default/bind ]; then
- . /etc/default/bind
- fi
-
-
- case "$1" in
- start)
- echo -n "Starting domain name service: named"
- start-stop-daemon --start --quiet --exec /usr/sbin/named \
- -- $PARAMS
- echo "."
- ;;
- stop)
- echo -n "Stopping domain name service: named"
- start-stop-daemon --stop --quiet \
- --pidfile /var/run/named.pid --exec /usr/sbin/named
- echo "."
- ;;
- restart)
- echo -n "Restarting domain name service: named"
- start-stop-daemon --stop --quiet \
- --pidfile /var/run/named.pid --exec /usr/sbin/named
- start-stop-daemon --start --verbose --exec /usr/sbin/named \
- -- $PARAMS
- echo "."
- ;;
- force-reload|reload)
- echo -n "Reloading configuration of domain name service: named"
- start-stop-daemon --stop --signal 1 --quiet \
- --pidfile /var/run/named.pid --exec /usr/sbin/named
- echo "."
- ;;
- *)
- echo "Usage: /etc/init.d/bind {start|stop|restart|reload|force-reload}" >&2
- exit 1
- ;;
- esac
-
- exit 0
+#!/bin/sh
+#
+# Original version by Robert Leslie
+# <rob@mars.org>, edited by iwj and cs
+
+test -x /usr/sbin/named || exit 0
+
+# Source defaults file.
+PARAMS=''
+if [ -f /etc/default/bind ]; then
+ . /etc/default/bind
+fi
+
+
+case "$1" in
+start)
+ echo -n "Starting domain name service: named"
+ start-stop-daemon --start --quiet --exec /usr/sbin/named \
+ -- $PARAMS
+ echo "."
+ ;;
+stop)
+ echo -n "Stopping domain name service: named"
+ start-stop-daemon --stop --quiet \
+ --pidfile /var/run/named.pid --exec /usr/sbin/named
+ echo "."
+ ;;
+restart)
+ echo -n "Restarting domain name service: named"
+ start-stop-daemon --stop --quiet \
+ --pidfile /var/run/named.pid --exec /usr/sbin/named
+ start-stop-daemon --start --verbose --exec /usr/sbin/named \
+ -- $PARAMS
+ echo "."
+ ;;
+force-reload|reload)
+ echo -n "Reloading configuration of domain name service: named"
+ start-stop-daemon --stop --signal 1 --quiet \
+ --pidfile /var/run/named.pid --exec /usr/sbin/named
+ echo "."
+ ;;
+*)
+ echo "Usage: /etc/init.d/bind {start|stop|restart|reload|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
</example>
</p>
</p>
<p>
<example>
- # Specified parameters to pass to named. See named(8).
- # You may uncomment the following line, and edit to taste.
- #PARAMS="-u nobody"
+# Specified parameters to pass to named. See named(8).
+# You may uncomment the following line, and edit to taste.
+#PARAMS="-u nobody"
</example>
</p>
and having named running in all runlevels, it can say in
its <tt>postinst</tt>:
<example>
- update-rc.d bind defaults >/dev/null
+update-rc.d bind defaults >/dev/null
</example>
And in its <tt>postrm</tt>, to remove the links when the
package is purged:
<example>
- if [ purge = "$1" ]; then
- update-rc.d bind remove >/dev/null
- fi
+if [ purge = "$1" ]; then
+ update-rc.d bind remove >/dev/null
+fi
</example></p>
</sect1></sect>
via cron, it should place a file with the name of the
package in one of the following directories:
<example>
- /etc/cron.daily
- /etc/cron.weekly
- /etc/cron.monthly
+/etc/cron.daily
+/etc/cron.weekly
+/etc/cron.monthly
</example>
As these directory names imply, the files within them are
executed on a daily, weekly, or monthly basis,
mention ``him'' directly. For example, if you think
of saying
<example>
- I'm starting network daemons: nfsd mountd.
+I'm starting network daemons: nfsd mountd.
</example>
just say
<example>
- Starting network daemons: nfsd mountd.
- </example></p></item>
- </list></p>
+Starting network daemons: nfsd mountd.
+ </example>
+ </p>
+ </item>
+ </list>
+ </p>
<p>
The following formats should be used</p>
daemons. The output should look like this (a single
line, no leading spaces):
<example>
- Starting <description>: <daemon-1> <daemon-2> <...> <daemon-n>.
+Starting <description>: <daemon-1> <daemon-2> <...> <daemon-n>.
</example>
The <description> should describe the subsystem
the daemon or set of daemons are part of, while
<p>
For example, the output of /etc/init.d/lpd would look like:
<example>
- Starting printer spooler: lpd.
+Starting printer spooler: lpd.
</example></p>
<p>
This can be achieved by saying
<example>
- echo -n "Starting printer spooler: lpd"
- start-stop-daemon --start --quiet lpd
- echo "."
+echo -n "Starting printer spooler: lpd"
+start-stop-daemon --start --quiet lpd
+echo "."
</example>
in the script. If you have more than one daemon to
start, you should do the following:
<example>
- echo -n "Starting remote file system services:"
- echo -n " nfsd"; start-stop-daemon --start --quiet nfsd
- echo -n " mountd"; start-stop-daemon --start --quiet mountd
- echo -n " ugidd"; start-stop-daemon --start --quiet ugidd
- echo "."
+echo -n "Starting remote file system services:"
+echo -n " nfsd"; start-stop-daemon --start --quiet nfsd
+echo -n " mountd"; start-stop-daemon --start --quiet mountd
+echo -n " ugidd"; start-stop-daemon --start --quiet ugidd
+echo "."
</example>
This makes it possible for the user to see what takes
so long and when the final daemon has been
example above the system administrator can easily
comment out a line if he don't wants to start a
specific daemon, while the displayed message still
- looks good.</p></item>
-
+ looks good.
+ </p>
+ </item>
<item>
<p>when something needs to be configured.</p>
If you have to set up different parameters of the
system upon boot up, you should use this format:
<example>
- Setting <parameter> to `<value>'.
- </example></p>
+Setting <parameter> to `<value>'.
+ </example>
+ </p>
<p>
You can use the following echo statement to get the quotes right:
<example>
- echo "Setting DNS domainname to \`"value"'."
- </example></p>
+echo "Setting DNS domainname to \`"value"'."
+ </example>
+ </p>
<p>
Note that the left quotation mark (`) is different
- from the right (').</p></item>
+ from the right (').
+ </p>
+ </item>
<item>
<p>when a daemon is stopped.</p>
<p>
So stopping the printer daemon will like like this:
<example>
- Stopping printer spooler: lpd.
+Stopping printer spooler: lpd.
</example></p></item>
<item>
via `netdate' or killing all processes when the system
comes down. Your message should like this:
<example>
- Doing something very useful...done.
+Doing something very useful...done.
</example>
You should print the `done.' right after the job has been completed,
so that the user gets informed why he has to wait. You can get this
behavior by saying
<example>
- echo -n "Doing something very useful..."
- do_something
- echo "done."
+echo -n "Doing something very useful..."
+do_something
+echo "done."
</example>
- in your script.</p></item>
+ in your script.
+ </p>
+ </item>
<item>
<p>when the configuration is reloaded.</p>
When a daemon is forced to reload its configuration
files you should use the following format:
<example>
- Reloading <daemon's-name> configuration...done.
- </example></p></item>
+Reloading <daemon's-name> configuration...done.
+ </example>
+ </p>
+ </item>
<item>
<p>when none of the above rules apply.</p>
If you have to print a message that doesn't fit into
the styles described above, you can use something
appropriate, but please have a look at the overall
- rules listed above.</p></item>
- </list></p></sect>
-
+ rules listed above.
+ </p>
+ </item>
+ </list>
+ </p>
+ </sect>
<sect>
<heading>Menus</heading>
Here is an example of a wrapper script for this purpose:
<example>
- #!/bin/sh
- BAR=${BAR:-/var/lib/fubar}
- export BAR
- exec /usr/lib/foo/foo "$@"
+#!/bin/sh
+BAR=${BAR:-/var/lib/fubar}
+export BAR
+exec /usr/lib/foo/foo "$@"
</example></p>
<p>
<p>
Generally the following compilation parameters should be used:
<example>
- CC = gcc
- CFLAGS = -O2 -Wall # sane warning options vary between programs
- LDFLAGS = # none
- install -s # (or use strip on the files in debian/tmp)
+CC = gcc
+CFLAGS = -O2 -Wall # sane warning options vary between programs
+LDFLAGS = # none
+install -s # (or use strip on the files in debian/tmp)
</example></p>
<p>
<example>
- CFLAGS = -O2 -Wall
- INSTALL = install
- INSTALL_FILE = $(INSTALL) -p -o root -g root -m 644
- INSTALL_PROGRAM = $(INSTALL) -p -o root -g root -m 755
- INSTALL_SCRIPT = $(INSTALL) -p -o root -g root -m 755
- INSTALL_DIR = $(INSTALL) -p -d -o root -g root -m 755
-
- ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -g
- endif
- ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
- INSTALL_PROGRAM += -s
- endif
+CFLAGS = -O2 -Wall
+INSTALL = install
+INSTALL_FILE = $(INSTALL) -p -o root -g root -m 644
+INSTALL_PROGRAM = $(INSTALL) -p -o root -g root -m 755
+INSTALL_SCRIPT = $(INSTALL) -p -o root -g root -m 755
+INSTALL_DIR = $(INSTALL) -p -d -o root -g root -m 755
+
+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
+CFLAGS += -g
+endif
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+INSTALL_PROGRAM += -s
+endif
</example>
Please note that the above example is merely informative,
Note that all installed shared libraries should be
stripped with
<example>
- strip --strip-unneeded <your-lib>
+strip --strip-unneeded <your-lib>
</example>
(The option `--strip-unneeded' makes <tt>strip</tt> remove
only the symbols which aren't needed for relocation
For example, in your <prgn>Makefile</prgn> or
<tt>debian/rules</tt>, do things like:
<example>
- ln -fs gcc $(prefix)/bin/cc
- ln -fs gcc debian/tmp/usr/bin/cc
- ln -fs ../sbin/sendmail $(prefix)/bin/runq
- ln -fs ../sbin/sendmail debian/tmp/usr/bin/runq
+ln -fs gcc $(prefix)/bin/cc
+ln -fs gcc debian/tmp/usr/bin/cc
+ln -fs ../sbin/sendmail $(prefix)/bin/runq
+ln -fs ../sbin/sendmail debian/tmp/usr/bin/runq
</example></p>
<p>
file (for more information see <manref name="logrotate"
section="8">):
<example>
- /var/log/foo/* {
- rotate 12
- weekly
- compress
- postrotate
- /etc/init.d/foo force-reload
- endscript
- }
+/var/log/foo/* {
+rotate 12
+weekly
+compress
+postrotate
+/etc/init.d/foo force-reload
+endscript
+}
</example>
Which rotates all files under `/var/log/foo', saves 12
compressed generations, and sends a HUP signal at the end of
If a program needs to specify an <em>architecture specification
string</em> in some place, the following format should be used:
<example>
- <arch>-<os>
+<arch>-<os>
</example>
where `<arch>' is one of the following: i386, alpha, arm, m68k,
powerpc, sparc and `<os>' is one of: linux, gnu. Use
<p>Cgi-bin executable files are installed in the
directory
<example>
- /usr/lib/cgi-bin/<cgi-bin-name>
+/usr/lib/cgi-bin/<cgi-bin-name>
</example>
and should be referred to as
<example>
- http://localhost/cgi-bin/<cgi-bin-name>
- </example></p></item>
-
+http://localhost/cgi-bin/<cgi-bin-name>
+ </example>
+ </p>
+ </item>
<item><p>Access to html documents</p>
backward compatibility, see <ref id="usrdoc"></footnote>
and can be referred to as
<example>
- http://localhost/doc/<package>/<filename>
- </example></p></item>
-
+http://localhost/doc/<package>/<filename>
+ </example>
+ </p>
+ </item>
<item><p>Web Document Root</p>
register the Web Application via the menu package. If
access to the web-root is unavoidable then use
<example>
- /var/www
+/var/www
</example>
as the Document Root. This might be just a
symbolic link to the location where the sysadmin has
name will not just be used by that package. For example, in
this situation the INN package says:
<example>
- Please enter the `mail name' of your system. This is the
- hostname portion of the address to be shown on outgoing
- news and mail messages. The default is
- <var>syshostname</var>, your system's host name. Mail
- name [`<var>syshostname</var>']:
+Please enter the `mail name' of your system. This is the
+hostname portion of the address to be shown on outgoing
+news and mail messages. The default is
+<var>syshostname</var>, your system's host name. Mail
+name [`<var>syshostname</var>']:
</example>
where <var>syshostname</var> is the output of <tt>hostname
- --fqdn</tt>.</p></sect>
-
+ --fqdn</tt>.
+ </p>
+ </sect>
<sect>
<heading>News system configuration</heading>
may be provided. This symbolic link can be created from
<tt>debian/rules</tt> like this:
<example>
- ln -s ../man7/undocumented.7.gz \
- debian/tmp/usr/share/man/man[1-9]/the_requested_manpage.[1-9].gz
+ln -s ../man7/undocumented.7.gz \
+debian/tmp/usr/share/man/man[1-9]/the_requested_manpage.[1-9].gz
</example>
This manpage claims that the lack of a manpage has been
reported as a bug, so you may only do this if it really has
<tt>dir</tt>
file, in its post-installation script:
<example>
- install-info --quiet --section Development Development \
- /usr/share/info/foobar.info
+install-info --quiet --section Development Development \
+/usr/share/info/foobar.info
</example></p>
<p>
<p>
You should remove the entries in the pre-removal script:
<example>
- install-info --quiet --remove /usr/share/info/foobar.info
+install-info --quiet --remove /usr/share/info/foobar.info
</example></p>
<p>
this is to put the following in the package's
<prgn>postinst</prgn>:
<example>
- if [ "$1" = "configure" ]; then
- if [ -d /usr/doc -a ! -e /usr/doc/#PACKAGE# \
- -a -d /usr/share/doc/#PACKAGE# ]; then
- ln -sf ../share/doc/#PACKAGE# /usr/doc/#PACKAGE#
- fi
- fi
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/#PACKAGE# \
+ -a -d /usr/share/doc/#PACKAGE# ]; then
+ ln -sf ../share/doc/#PACKAGE# /usr/doc/#PACKAGE#
+ fi
+fi
</example>
And the following in the package's <prgn>prerm</prgn>:
<example>
- if [ \( "$1" = "upgrade" -o "$1" = "remove" \) \
- -a -L /usr/doc/#PACKAGE# ]; then
- rm -f /usr/doc/#PACKAGE#
- fi
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) \
+ -a -L /usr/doc/#PACKAGE# ]; then
+ rm -f /usr/doc/#PACKAGE#
+fi
</example>
</p>
</sect>