How and why to create -dbg, -dev, -doc packages?

I'm writing an Ubuntu package for a package which essentially provides a number of libraries and headers which then be used to build other software. The package also breaks up in smaller subpackages which are interdependent; in this sense the package is quite similar to boost.

I noticed that packages like boost provide

[...]
libboost-dbg
libboost-dev
libboost-doc
[...]
libboost-all-dev
[...]

but nothing that goes by the name boost or libboost.

  • What is the idea behind this?
  • What are the purposes of the -dbg, -dev, and -doc packages?
  • Are there any instructions provided on how to write build files for those packages?

Idea & Purpose

The main reason for separating out these different packages has to do with disk space and download speed. In particular, it is a big concern for mirror space since it means distributing multiple copies of the data. By making the foo-common, foo-data, or foo-doc packages Architecture: all, we only keep one copy of of the data in the archive instead of having it copied with each architecture (e.g. i386, amd64, ect...). Debugging symbols are not needed by most users and just end up making the package download take longer.

For packages in the official Ubuntu archives, there is actually no reason to create -dbg packages manually. The build machines automatically strip out the debugging symbols and put them into -dbgsym packages hosted on ddebs.ubuntu.com. (See: Debug Symbol Packages) -dbg packages that do exist are usually simply carried over from Debian.

Instructions

As for implementation, take a look at this question:

  • How to have Debian packaging generate two packages given an upstream source archive?

Briefly, new stanzas need to be created in debian/control for each package. Then debian/foo-*.install files need to be created as well. This will allow dh_install to put the right contents into the right packages.

The foo.install for the main binary package might look like:

usr/bin/
usr/lib/

foo-common.install, foo-data.install, foo-doc.install, or whatever:

/usr/share/doc/
/usr/share/icons/
/usr/share/foo/
/usr/share/locale/

And for foo-dev:

/usr/include/
/usr/lib/pkgconfig
/usr/lib/*.so

Creating the foo-dbg package requires editing debian/rules as normally dh_strip will strip out debugging symbols. So we need to override that behavior:

.PHONY: override_dh_strip
override_dh_strip:
        dh_strip --dbg-package=foo-dbg
  • Further reading: http://wiki.debian.org/DebugPackage

Boost is a complex example, let's look at a simpler one first.

In precise, the openssl source package provides 5 binary packages:

  • libssl1.0.0 contains the OpenSSL dynamic library, version 1.0.0. That's what programs linked against this library need to run. The package name contains a version number because you might have other versions of the library installed at the same time, if you have other programs linked against another version that isn't binary-compatible with 1.0.0.
  • openssl contains command line tools that use the OpenSSL library. Even if you have multiple versions of the library, you don't need multiple versions of these tools: there's just one /usr/bin/openssl and associated tools, data and documentation.
  • libssl-dev contains the files that you need if you want to compile a program that links against OpenSSL. There are C header files (*.h), libraries for linking (*.a, *.so), and a few assorted files.
  • libssl-doc contains documentation for the OpenSSL library. You only need this package if you're going to write programs that use the library.
  • libssl1.0.0-dbg contains debugging symbols. It's only useful for people who debug the OpenSSL library or programs that use it. andrewsomething's answer has more information on these -dbg packages.

In addition, precise contains an older version of the library, libssl0.9.8, because there are programs that are still linked against the older version.

Other packages you might see are bindings for languages other than C. OpenSSL doesn't ship with any (there are bindings to OpenSSL for other languages, but they don't come from the same source). An example is sqlite3, which ships with TCL bindings.

The main reason for splitting packages like this is that different packages have different target audiences. A system where no one ever compiles anything only needs the core lib package, and maybe the command line tools; they'll be installed automatically from dependencies if required. If someone wants to compile a program that uses the library, they need the -dev package. If someone wants to write a program that uses the library, they need the -doc package.

So what about Boost? It follows the same structure, but because Boost is a huge library, it's broken up into many smaller packages: libboost-*1.46.1 and libboost-*1.46-dev. In precise, there is only one version of Boost, 1.46, but oneiric had both 1.42 and 1.46. There is also a metapackage boost-defaults that pulls in the versioned package as a dependency.

Looking at libhangul, in addition to the dynamic library package libhangul1 and the development package libhangul-dev, there's a package libhangul-data. This package contains additional data that is required by the library. Even if you have multiple versions of the library, they can share the -data package. Also, the package is architecture-independent. Software that contains a large amount of architecture-independent data is split into architecture-dependent and architecture-independent packages, to save space on distribution sites. Another suffix with a similar meaning is -common.

Ubuntu and Debian packaging rules are very similar, so material about making Debian packages also applies to Ubuntu. In fact, you can have the same source package for Debian and Ubuntu; the only thing that makes Debian and Ubuntu packages different is compiling them against different library versionsm, and that's no more than the difference between different releases of Ubuntu. Have the Debian developer documentation at hand, especially the Debian Policy Manual and the Developer's Reference; see the New Maintainer's Guide for an introduction. Ignore the parts about working with the Debian project and so on, just read the parts about making a package. dh_make is a good way to get started with a deb package (you'll want to select “Library”).