Debian Package Building
Introduction
Debian packages (.deb
files) are the standard software distribution format for Debian and Debian-based Linux distributions like Ubuntu, Linux Mint, and Pop!_OS. Understanding how to build these packages is a valuable skill for developers who want to distribute their applications reliably on these platforms.
In this guide, we'll walk through the process of creating Debian packages from scratch. You'll learn how to organize your source code, define package metadata, handle dependencies, and build a proper .deb
file that conforms to Debian packaging standards.
Prerequisites
Before we begin, ensure you have the following installed on your Debian-based system:
sudo apt update
sudo apt install build-essential devscripts debhelper dh-make fakeroot lintian
These tools provide the essential build environment for Debian packaging.
Understanding Debian Package Structure
A Debian package consists of the following components:
Building Your First Debian Package
Let's create a simple Debian package for a "Hello World" application. We'll go through each step of the process.
Step 1: Create a Basic Project
First, let's create a simple C program:
mkdir -p hello-deb/src
cd hello-deb/src
Create hello.c
:
#include <stdio.h>
int main() {
printf("Hello, Debian packaging world!
");
return 0;
}
Create a Makefile:
all: hello
hello: hello.c
gcc -o hello hello.c
install:
mkdir -p $(DESTDIR)/usr/bin
install -m 755 hello $(DESTDIR)/usr/bin
clean:
rm -f hello
Step 2: Prepare the Package Source
Return to the main directory and prepare the package:
cd ..
mkdir -p debian
Step 3: Create Essential Debian Files
Now we'll create the necessary files in the debian
directory:
control file:
Source: hello-deb
Section: utils
Priority: optional
Maintainer: Your Name <[email protected]>
Build-Depends: debhelper-compat (= 13), gcc
Standards-Version: 4.5.1
Homepage: https://example.com/hello-deb
Package: hello-deb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Simple hello world Debian package example
This package provides a basic "Hello World" program to
demonstrate Debian packaging concepts. It's a simple
C program that prints a greeting message.
changelog file:
hello-deb (1.0-1) unstable; urgency=medium
* Initial release
-- Your Name <[email protected]> Thu, 01 Jan 2023 12:00:00 +0000
rules file:
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_build:
$(MAKE) -C src
override_dh_auto_install:
$(MAKE) -C src install DESTDIR=$$(pwd)/debian/hello-deb
copyright file:
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: hello-deb
Source: https://example.com/hello-deb
Files: *
Copyright: 2023 Your Name <[email protected]>
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Make the rules file executable:
chmod +x debian/rules
compat file (just contains a version number):
13
source/format file:
mkdir -p debian/source
echo "3.0 (native)" > debian/source/format
Step 4: Build the Package
Now, let's build the package:
dpkg-buildpackage -us -uc -b
This command will:
-us
: Skip signing the source package-uc
: Skip signing the .changes file-b
: Build a binary package only
If successful, you'll find the .deb
file in the parent directory.
Step 5: Verify the Package
Check your package for conformity with Debian standards:
lintian ../hello-deb_1.0-1_amd64.deb
Install your package:
sudo dpkg -i ../hello-deb_1.0-1_amd64.deb
Test the installed application:
hello-deb
# Output: Hello, Debian packaging world!
Advanced Packaging Concepts
Managing Dependencies
Dependencies are defined in the control
file:
Depends: ${shlibs:Depends}, ${misc:Depends}, libsomething (>= 1.2.3)
${shlibs:Depends}
: Automatically detects library dependencies${misc:Depends}
: Adds dependencies required by debhelper- You can specify other package dependencies with version constraints
Configuration Files
To manage configuration files correctly, list them in a file called debian/conffiles
:
/etc/hello-deb/config.conf
Package Versioning
Debian version numbers typically look like: [epoch:]upstream_version-debian_revision
epoch
: Optional number used to correct ordering mistakes (rarely needed)upstream_version
: The version of the original softwaredebian_revision
: The revision of the Debian package
For example: 2:1.4.5-3ubuntu2
Creating Multiple Packages from One Source
You can define multiple packages in the control
file:
Source: my-project
# [...source package details...]
Package: my-app
# [...binary package details...]
Package: my-app-dev
Architecture: all
Depends: my-app (= ${binary:Version}), ${misc:Depends}
Description: Development files for my-app
This package contains header files and libraries necessary for developing
applications that use my-app.
Real-World Example: Packaging a Python Application
Let's create a more practical example by packaging a simple Python application:
Project Structure:
mypy-app/
├── mypyapp/
│ ├── __init__.py
│ └── main.py
├── setup.py
└── debian/
├── control
├── rules
├── changelog
└── ...
mypyapp/main.py:
#!/usr/bin/env python3
def main():
print("Hello from my Python Debian package!")
if __name__ == "__main__":
main()
setup.py:
from setuptools import setup, find_packages
setup(
name="mypyapp",
version="0.1",
packages=find_packages(),
entry_points={
'console_scripts': [
'mypyapp=mypyapp.main:main',
],
},
)
debian/control:
Source: mypyapp
Section: python
Priority: optional
Maintainer: Your Name <[email protected]>
Build-Depends: debhelper-compat (= 13), dh-python, python3-all, python3-setuptools
Standards-Version: 4.5.1
Homepage: https://example.com/mypyapp
Package: python3-mypyapp
Architecture: all
Depends: ${python3:Depends}, ${misc:Depends}
Description: Example Python application in a Debian package
This package provides a simple Python application that
demonstrates Debian packaging for Python projects.
debian/rules:
#!/usr/bin/make -f
export PYBUILD_NAME=mypyapp
%:
dh $@ --with python3 --buildsystem=pybuild
Build the package using the same commands as before.
Automating Package Building with Git-BuildPackage
For more complex projects, consider using git-buildpackage (gbp) to automate the packaging process:
sudo apt install git-buildpackage
Basic workflow:
-
Initialize a git repository for your package:
bashgbp import-orig --pristine-tar ../myapp-1.0.tar.gz
-
Make packaging changes and commit them.
-
Build the package:
bashgbp buildpackage
Package Repositories
To distribute your packages, you might want to set up a repository:
# Install tools
sudo apt install reprepro gnupg
# Create a GPG key for signing packages
gpg --full-generate-key
# Set up a basic repository structure
mkdir -p repo/conf
Create repo/conf/distributions
:
Origin: Your Repository
Label: Your Repository
Codename: focal
Architectures: i386 amd64 source
Components: main
Description: My Personal Package Repository
SignWith: [your-gpg-key-id]
Add your package to the repository:
reprepro -b repo includedeb focal ../hello-deb_1.0-1_amd64.deb
Users can then add your repository to their sources:
echo "deb [signed-by=/usr/share/keyrings/your-key.gpg] http://your-repo-url focal main" | sudo tee /etc/apt/sources.list.d/your-repo.list
Summary
In this guide, we've covered:
- The basic structure of Debian packages
- Essential files needed for packaging
- Step-by-step instructions for building a simple package
- Advanced packaging concepts like dependencies and versioning
- A real-world example with Python
- Automated tools for package management
- Setting up a package repository
Building Debian packages requires attention to detail, but it ensures your software can be installed, upgraded, and removed cleanly on Debian-based systems. The skills learned here apply to other packaging systems as well, as the concepts of metadata, dependencies, and build processes are universal in software distribution.
Exercises
- Create a Debian package for a simple bash script that displays system information.
- Modify the Python example to add configuration files in
/etc
. - Create a package with documentation installed to
/usr/share/doc
. - Build a package that contains multiple binaries from a single source.
- Set up a local repository and publish your packages to it.
Additional Resources
- Debian New Maintainers' Guide
- Debian Policy Manual
- Debian Developer's Reference
- Ubuntu Packaging Guide
man debhelper
man dh_make
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)