CMake has become our C/C++ build tool of choice because it provides good cross-platform support and very reasonable IDE (Visual Studio, CLion, QtCreator) integration. Another very nice feature is the included packaging support using the CPack module. It allows to create native deployable artifacts for a plethora of systems including NSIS-Installer for Windows, RPM and Deb for Linux, DMG for Mac OS X and a couple more.
While all these binary generators share some CPACK-variables there are specific variables for each generator to use exclusive packaging system features or requirements.
Deb-packaging features
The debian package management system used not only by Debian but also by Ubuntu, Raspbian and many other Linux distributions. In addition to dependency handling and versioning packagers can use several other features, namely:
- Specifying a section for the packaged software, e.g. Development, Games, Science etc.
- Specifying package priorities like optional, required, important, standard
- Specifying the relation to other packages like breaks, enhances, conflicts, replaces and so on
- Using maintainer scripts to customize the installation and removal process like pre- and post-install, pre- and post-removal
- Dealing with configuration files to protect end user customizations
- Installing and linking files and much more without writing shell scripts using
${project-name}.{install | links | ...}
files
All these make the software easier to package or easier to manage by your end users.
Using deb-features with CMake
Many of the mentioned features are directly available as appropriately named CMake-variables all starting with CPACK_DEBIAN_
. I would like to specifically mention the CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
variable where you can set the maintainer scripts and one of my favorite features: conffiles.
Deb protects files under /etc
from accidental overwriting by default. If you want to protect files located somewhere else you specify them in a file called conffiles
each on a separate line:
/opt/myproject/myproject.conf /opt/myproject/myproject.properties
If the user made changes to these files she will be asked what to do when updating the package:
- keep the own version
- use the maintainer version
- review the situation and merge manually.
For extra security files like myproject.conf.dpkg-dist
and myproject.conf.dpkg-old
are created so no changes are lost.
Unfortunately, I did not get the linking feature working without using maintainer scripts. Nevertheless I advise you to use CMake for your packaging work instead of packaging using the native debhelper way.
It is much more natural for a CMake-based project and you can reuse much of your metadata for other target platforms. It also shields you from a lot of the gory details of debian packaging without removing too much of the power of deb-packages.