How to Build a Debian .deb Installer Package

How to Build a Debian .deb Installer Package

The following demonstrates how to create a .deb installer package for Debian (and related Linux distros like Ubuntu) that can be installed with dpkg. In many distros simply double clicking on a .deb file will also install it. This is also the format used by many repos for these particular distros and that common package manager utilities understand e.g. apt-get installs .deb files.

A Debian installer is simply a Gnu “ar” archive containing the files corresponding the package together with a “control” file which describes the content and contains metadata. A utility called dpkg-deb is supplied that can build these archives.

If you want to unpack an existing .deb file and see what’s inside it and use it as a guide, it can be done like this:

ar x the_package.deb

To create your own deb file:

  • Firstly create a directory to contain the package content.

  • Next create a text file called “control” with the following format and fill in the details as appropriate for your package:

Package: MyAwesomePackage
Version: 1.0.1
Priority: optional
Section: utils
Architecture: amd64
Maintainer: Bob Maintainer <bob@bobthemaintainer>
Depends: libc6 (>= 2.34), libgcc-s1 (>= 4.2)
Homepage: https://github.com/mygithub/repo
Description: Does awesome stuff

A priority of “optional” will usually be right for most packages.

The “Depends” parameter describes the dependencies of the main binary. It is not essential to have this line in the control file to create a working debian installer, however verification checks we will do later with the lintian utility to confirm we have a valid .deb file require this line to pass. If you do not know what the exact dependencies of your executable are, dpkg-shlibdeps can do it and produce the “depends” parameter in the expected format, although it’s not the easiest utility in the world to use and has some quirks. The way I got it to work is as follows:

dpkg-shlibdeps requires the above control file to be at this specific path relative to the directory where you run the command:

debian/control

For some reason you need to add a “Source” parameter to the control file to get it to work but the parameter can contain anything i.e. you need a line like this present in your control file (you can remove the line later after running the command):

Source: anything

Then run this (in the directory one level above the debian directory that contains the control file):

dpkg-shlibdeps -O /path/to/your/executable

And it should automatically determine the dependencies of the executable and tell you what to put on the depends line:

shlibs:Depends=libc6 (>= 2.34), libgcc-s1 (>= 4.2)

  • You need to create a file called “changelog” that describes the version history of your package and has the following format. This file is not essential but is required to pass verification checks:
MyAwesomeExecutable (1.0.1) unstable; urgency=low

  * Fantastic upgrades ocurred
  
 -- Bob Maintainer <bob@bobthemaintainer>  Wed, 21 Feb 2024 18:00:00 -0000

MyAwesomeExecutable (1.0.0) unstable; urgency=low

  * Things happened

 -- Bob Maintainer <bob@bobthemaintainer> Fri, 16 Feb 2024 18:00:00 -0000
  • Finally you need a “copyright” file as follows, which includes the license for your package. Again, this file is not essential but is required to pass checks:
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: MyAwesomePackage
Upstream-Contact: Bob Maintainer <bob@bobthemaintainer>
Files: *
Copyright: 2021-2024 Bob Maintainer <bob@bobthemaintainer>
License: MIT
 The MIT License (MIT)
 .
 Copyright © 2021 - 2024 Bob Maintainer
 .
 Permission is hereby granted, free of charge, to any person obtaining a copy
 <more license here>
  • Next lay out your package directory structure as follows. Here we have the control file, an executable, a man page for the executable, the changelog and the copyright file. Note how the structure mirrors a typical UNIX file system layout. When the dpgk package manager utility installs out .deb file, it will take each file from the archive and place it in the same location on the file system. If for example you don’t want your executable to appear in /usr/bin/ and want it installed somewhere else, simply create a directory at the relevant path and put your executable there.
MyAwesomePackage/DEBIAN/control
MyAwesomePackage/usr/bin/myawesomeexecutable
MyAwesomePackage/usr/share/man/man1/myawesomesoftware.1
MyAwesomePackage/usr/share/doc/myawesomeexecutable/changelog.gz
MyAwesomePackage/usr/share/doc/myawesomeexecutable/copyright
  • Directories should generally have 755 permissions and files should be 644.

  • The executable to be installed needs to be stripped of debugging symbols (use strip)

  • The changelog file needs to be gzip compressed at -9 level i.e. gzip -9 changelog

  • Now run:

dpkg-deb --build --root-owner-group /path/to/MyAwesomePackage/

And you should end up with your package.

Finally, you should run lintian which is a utility that confirms your .deb installer conforms to Debian standards:

lintian myawesomepackage.deb

Conventionally your .deb file should be named with the package name first, followed by the version and then the architecture e.g.:

myawesomepackage_1.0.1_amd64.deb