Packaging

Building Debian packages is the first-half of distributing software in their ecosystem. In private use, it’s how you can build it in one place and and install it somewhere else. Keeps you from installing a bunch of build-tools (which can get big) everywhere.

Here’s an example with libTorrent and rTorrent.

LibTorrent

I’ll use the example of libtorrent here.

Prerequisites

# Install the deb build basics, plus a couple things the source needs 
sudo apt install git debhelper devscripts dh-make libcppunit-dev pkg-config

# We want the latest release so check GitHub as needed
git clone https://github.com/rakshasa/libtorrent --branch v0.16.6 --depth 1 libtorrent-0.16.6

# If you cloned head for some reason, you can set the package version explicitly 
# dh_make --createorig -s -y -p libtorrent_0.16.6
dh_make --createorig -s -y

# The readme says it needs (in addition to make and autoconf) curl-libcurlpp-dev
sudo apt install libcurlpp-dev

# Create the Debian template files
cd libtorrent-*
dh_make --createorig -s -y

Edit the control file with the build details. This git project will actually build three packages;

libtorrent36 The main package you’re building
libtorrent The source package. The other packages will use this when they build
libtorrent-dev The development files for anyone else building with libTorrent

Notice that we put 36 at the end of the package. The the Debian Policy Manual says to add the SONAME (shared object name) to the end to keep things separate.

You can get that from the LibTool number in the autoconf file: grep LIBTORRENT_CURRENT= libtorrent*/configure. You can consult the Debian Library Packaging Guide for more info.

vi debian/control
Source: libtorrent
Section: libs
Priority: optional
Maintainer: you <[email protected]>
Rules-Requires-Root: no
Build-Depends: debhelper-compat (= 13),
               pkg-config,
               libtool,
               automake,
               autoconf,
               libcppunit-dev,
               libcurlpp-dev,
               libcurl4-openssl-dev,
               libssl-dev,
               zlib1g-dev
Standards-Version: 4.7.2
Homepage: https://github.com/rakshasa/libtorrent

Package: libtorrent36
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: BitTorrent library with focus on high performance (Rakshasa version)
 libtorrent is a BitTorrent library written in C++ with a focus on
 high performance and good code. This package contains the shared
 library (SONAME 36).

Package: libtorrent-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libtorrent36 (= ${binary:Version}),
         libsigc++-2.0-dev,
         libssl-dev,
         ${misc:Depends}
Description: development files for libtorrent (Rakshasa version)
 This package contains the header files and static libraries for
 developing applications that use Rakshasa's libtorrent.

Add a rule to handle the lack of a Makefile and make sure it looks in tmp for files it will need between the packages

vi debian/rules
...
...

%:
        dh $@

# This override runs BEFORE the automatic configuration step
override_dh_autoreconf:
        autoreconf -ivf
        dh_autoreconf

# dh_make generated override targets.
# This is an example for Cmake (see <https://bugs.debian.org/641051>).

# Force installation to debian/tmp so multiple packages can pick from it
override_dh_auto_install:
        dh_auto_install --destdir=debian/tmp

Create some install files so the packager knows what output files go with what package

vi debian/libtorrent36.install
usr/lib/*/libtorrent.so.36*
vi debian/libtorrent-dev.install
usr/include/torrent/*
usr/lib/*/libtorrent.so
usr/lib/*/pkgconfig/libtorrent.pc

The project builds a ’libtool archive’ file that the packager frowns upon. Add a rule so it knows explicitly that we are going to package it.

echo "usr/lib/*/libtorrent.la" > debian/not-installed

Run the build

debuild -us -uc

Install with

sudo dpkg -i libtorrent36_0.16.6-1_amd64.deb libtorrent-dev_0.16.6-1_amd64.deb

Troubleshooting

You may need to clean up, add an ignore file and re-build

# Create a ignore file so the builder is OK with the directory have a previous build product in it
vi debian/source/options
extend-diff-ignore = "(^|/)(Makefile\.in|config\.h\.in|scripts/.*\.m4|configure|aclocal\.m4|compile|depcomp|install-sh|missing|ltmain\.sh|config\.sub|config\.guess)$"
debian/rules clean

debuild -us -uc

RTorrent

You’ll need libTorrent, but hopefully you’ve just built it. If you haven’t installed it, do that now.

Note: You probably want XPC enabled as per https://github.com/rakshasa/rtorrent-doc/blob/master/RPC-Setup-XMLRPC.md. We’ll add a configure flag for that.

# Check the current version before you clone
git clone https://github.com/rakshasa/rtorrent --branch v0.16.6 --depth 1 rtorrent-0.16.6

sudo apt install libncurses-dev

# Create the Debian template files
cd rtorrent-*
dh_make --createorig -s -y

Change the debian/control file to be

Source: rtorrent
Section: net
Priority: optional
Maintainer: you <[email protected]>
Rules-Requires-Root: no
Build-Depends:
 debhelper-compat (= 13),
 pkg-config,
 libtool,
 automake,
 autoconf,
 libtorrent-dev,
 libncursesw5-dev,
 libcurl4-openssl-dev,
 libcppunit-dev,
 libxmlrpc-c++9-dev
Standards-Version: 4.7.2
Homepage: https://github.com/rakshasa/rtorrent
#Vcs-Browser: https://salsa.debian.org/debian/rtorrent
#Vcs-Git: https://salsa.debian.org/debian/rtorrent.git

Package: rtorrent
Architecture: any
Depends:
 ${shlibs:Depends},
 ${misc:Depends},
 adduser,
 tmux
Description: ncurses BitTorrent client based on libtorrent
 rtorrent is a BitTorrent client that uses ncurses and aims to be a
 lean, yet powerful terminal application.

Make the debian/rules like this:

#!/usr/bin/make -f

# See debhelper(7) (uncomment to enable).
# Output every command that modifies files on the build system.
#export DH_VERBOSE = 1


# See FEATURE AREAS in dpkg-buildflags(1).
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all

# See ENVIRONMENT in dpkg-buildflags(1).
# Package maintainers to append CFLAGS.
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
# Package maintainers to append LDFLAGS.
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed


%:
        dh $@

# Generate the configure script before building
override_dh_autoreconf:
        autoreconf -ivf
        dh_autoreconf

# dh_make generated override targets.
# This is an example for Cmake (see <https://bugs.debian.org/641051>).
#override_dh_auto_configure:
#       dh_auto_configure -- \
#       -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
override_dh_auto_configure:
        dh_auto_configure -- --with-xmlrpc-c

Include a service unit file

vi debian/rtorrent.service
[Unit]
Description=rTorrent System Service
After=network.target

[Service]
Type=forking
User=rtorrent
Group=rtorrent
WorkingDirectory=/var/lib/rtorrent
# Capture the stdin and out to send to the journal
ExecStart=/usr/bin/tmux new-session -d -s rtorrent 'rtorrent 2>&1'
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rtorrent
ExecStop=/usr/bin/tmux send-keys -t rtorrent C-q
TimeoutStopSec=30
Restart=on-failure

[Install]
WantedBy=multi-user.target

Add a template file.

vi debian/rtorrent.rc
# rTorrent System Configuration
directory.default.set = /var/lib/rtorrent/downloads
session.path.set = /var/lib/rtorrent/.session

# Set port statically for VPN incomming
network.port_range.set = 50000-50000
network.port_random.set = no

protocol.encryption.set = allow_incoming,try_outgoing,enable_retry

dht.mode.set = auto

# Adjust as needed for a remote web server if used. But secure thoroughly as 
# this interface allows for remote code execution (I've read)
network.scgi.open_port = 0.0.0.0:8080

# Use a unix domain socket if possible. 
# Make sure the webserver and rtorrent share a group and set permissions for that
#network.scgi.open_local = /home/user/rtorrent/rpc.socket
#schedule2 = scgi_permission,0,0,"execute.nothrow=chmod,\"g+w,o=\",/home/user/rtorrent/rpc.socket"

# Redirect all 'info', 'error', and 'critical' logs to the tmux screen (stdout) if desired.
log.add_output = "info", "stdout"
log.add_output = "error", "stdout"
log.add_output = "critical", "stdout"

Create debian/install so the template file is included

vi debian/install
debian/rtorrent.rc etc/

Create a post install to create a user and dirs

vi debian/postinst
#!/bin/sh
set -e

if [ "$1" = "configure" ]; then
    # Create system user if missing
    if ! getent passwd rtorrent >/dev/null; then
        adduser --system --group --home /var/lib/rtorrent \
                --shell /bin/false --quiet rtorrent
    fi

    # Create required directories
    mkdir -p /var/lib/rtorrent/downloads
    mkdir -p /var/lib/rtorrent/.session

    # Link the global config to the user's home
    if [ ! -f /var/lib/rtorrent/.rtorrent.rc ]; then
        ln -sf /etc/rtorrent.rc /var/lib/rtorrent/.rtorrent.rc
    fi

    # Fix permissions
    chown -R rtorrent:rtorrent /var/lib/rtorrent
fi

#DEBHELPER#

exit 0

Make it executable

chmod +x debian/postinst

Build as before

debuild -us -uc

And install

sudo dpkg -i rtorrent_0.16.6-1_amd64.deb

Start and attach with

sudo -u rtorrent tmux -L rtorrent attach -t rtorrent

Note:

To install on other servers

sudo apt install ./libtorrent* ./rtorrent_0.16.6-1_amd64.deb

Last modified April 1, 2026: build and media client initial (e0f2af6)