TL;DR
This post will walk you through creating a debian package from a simple hello world C program using debuild
.
Setup
On a debian-based system, install the following programs:
The debuild
tool
debuild is a convenient wrapper around dpkg-buildpackage, fakeroot, lintian, and debsign. It handles all the packaging linting, and signing for us. Let’s use it to package a simple “helloworld” program.
Our “Hello World” program
It consists of the source file main.c
:
And a Makefile
:
Building and Testing
Let’s make sure everything works before we package it up.
Run make
to build the program. This should create a helloworld
binary you can execute by running ./helloworld
.
You should see “Hi” printed to the screen.
Then, try installing the binary: run sudo make install
and now helloworld
should be in /usr/local/bin
.
Remove our test binary before continuing:
Packaging our program
Note: debuild
will make use of symlinks in it’s build process, so if you are using a Virtualbox or VMware Shared folder to build your package, it will not work.
Now that we’ve verified everything works, let’s create a debian package for it:
1. Create a debian/
folder
This is where all of our debian specific packaging files will go.
2. Create a debian/control
file
This file describes your package using debian control fields. Below we have defined a binary package and a corresponding source package (from which the binary package can be repackaged):
3. Create a debian/changelog
file
This file tracks all the changes to the package. You need a minimum of one entry to build a package.
The syntax of this file is tricky, so while you can create this file by hand, it’s recommended to use the debchange tool, or dch
.
To initially create the changelog, type:
This will bring up your $EDITOR
and let you edit the fields. Make sure you change UNRELEASED
to unstable
. Check out the dch
man page and the debian changelog policy for more details.
4. Create a debian/rules
file
This file tells debian specifically how to build your package. The most basic implementation just passes all calls to the original Makefile
created above:
Note: Make sure you use hard tabs here, since it uses the same format as Makefile
5. Create a debian/copyright
file
To pass lintian, you need a copyright file (however, it can be blank). Ours can be very simple:
6. Run debuild
to build your package.
Error!
If you were following along, you’ll notice the package doesn’t build and returns the following error:
This is because debuild
ran make install
and failed because it did not have permissions to write to /usr/local/bin/
(hardcoded in our Makefile
above).
As you can imagine, most software will not package cleanly out of the box for reasons like the above. In such cases, a more specific debian/rules
file will be needed. Let’s override the install
directive of our Makefile
during packaging in our debian/rules
file:
Now run debuild -us -uc
again and the package should build successfully. To see your built package, navigate backwards into the parent directory of the source folder. You should see:
Sign your package with GPG and debsign
Refer to our other post on this topic: GPG signing debian packages with debsign.
Conclusion
Creating debian packages gives you full control over how a program is compiled and the specific version being packaged. Uploading those packages to packagecloud lets you easily distribute them to all of your machines, exactly how you built it.