Debian Packaging

Build Debian Package

Install

sudo apt-get install gnupg pbuilder debootstrap quilt ubuntu-dev-tools dh-make packaging-dev

pbuilder Setup

Create the following folders:

sudo mkdir /usr/lib/pbuilder/hooks
sudo mkdir /var/cache/pbuilder/repo
sudo chmod 777 /var/cache/pbuilder/repo

Create /usr/lib/pbuilder/hooks/C10shell with:

#!/bin/sh
# invoke shell if build fails.

apt-get install -y --force-yes vim less bash
cd /tmp/buildd/*/debian/..
/bin/bash < /dev/tty > /dev/tty 2> /dev/tty

Make /usr/lib/pbuilder/hooks/C10shell executable:

sudo chmod +x /usr/lib/pbuilder/hooks/C10shell

Create /usr/lib/pbuilder/hooks/D05deps with:

#!/bin/sh
(cd /var/cache/pbuilder/repo; apt-ftparchive packages . > Packages && gzip -c Packages >Packages.gz)
apt-get update

Make /usr/lib/pbuilder/hooks/D05deps executable:

sudo chmod +x /usr/lib/pbuilder/hooks/D05deps

To enable ROS dependencies, create /usr/lib/pbuilder/hooks/D10addppa with:

#!/bin/sh

echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list
apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
apt-get update

Make /usr/lib/pbuilder/hooks/D10addppa executable:

sudo chmod +x /usr/lib/pbuilder/hooks/D10addppa

Create /etc/pbuilderrc with:

# this is your configuration file for pbuilder.
# the file in /usr/share/pbuilder/pbuilderrc is the default template.
# /etc/pbuilderrc is the one meant for editing.
#
# read pbuilderrc.5 document for notes on specific options.

BASETGZ=/var/cache/pbuilder/base.tgz
BUILDPLACE=/var/cache/pbuilder/build/
OTHERMIRROR="deb file:///var/cache/pbuilder/repo ./"
USEPROC=yes
USEDEVPTS=yes
USEDEVFS=no
BUILDRESULT=/var/cache/pbuilder/result/

REMOVEPACKAGES="lilo"
HOOKDIR="/usr/lib/pbuilder/hooks"
# make debconf not interact with user
export DEBIAN_FRONTEND="noninteractive"
DEBEMAIL=""
# for pbuilder debuild (sudo -E keeps the environment as-is)
BUILDSOURCEROOTCMD="fakeroot"
PBUILDERROOTCMD="sudo -E"

# command to satisfy build-dependencies; the default is an internal shell
# implementation which is relatively slow; there are two alternate
# implementations, the "experimental" implementation,
# "pbuilder-satisfydepends-experimental", which might be useful to pull
# packages from experimental or from repositories with a low APT Pin Priority,
# and the "aptitude" implementation, which will resolve build-dependencies and
# build-conflicts with aptitude which helps dealing with complex cases but does
# not support unsigned APT repositories
PBUILDERSATISFYDEPENDSCMD="/usr/lib/pbuilder/pbuilder-satisfydepends"

#Command-line option passed on to dpkg-buildpackage.
DEBBUILDOPTS=""

#APT configuration files directory
APTCONFDIR=""
# the username and ID used by pbuilder, inside chroot. Needs fakeroot, really
BUILDUSERID=1234
BUILDUSERNAME=pbuilder

# BINDMOUNTS is a space separated list of things to mount
# inside the chroot.
BINDMOUNTS="/var/cache/pbuilder/repo"

# Set the debootstrap variant to 'buildd' type.
# DEBOOTSTRAPOPTS[0]='--variant=buildd'
# or work around bug in debootstrap 3.0.0 (314858)
unset DEBOOTSTRAPOPTS

# Set the PATH I am going to use inside pbuilder: default is "/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"

# SHELL variable is used inside pbuilder by commands like 'su'; and they need sane values
export SHELL=/bin/bash

# The name of debootstrap command.
DEBOOTSTRAP="debootstrap"

# default file extension for pkgname-logfile
PKGNAME_LOGFILE_EXTENTION="_$(dpkg --print-architecture).build"

# default PKGNAME_LOGFILE
PKGNAME_LOGFILE=""

Create your personal ~/.pbuilderrc with:

# Proxy configuration
# Uncomment the next line if using apt-cacher-ng on the local machine
#export http_proxy=http://localhost:3142/
# Uncomment the next line if using squid-deb-proxy on the local machine.
#export http_proxy=http://localhost:8000/

# Allow untrusted packages (TODO: required for local packages???)
ALLOWUNTRUSTED=yes

# Codenames for Debian suites according to their alias. Update these when needed.
TESTING_CODENAME="sid"
STABLE_CODENAME="jessie"
STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports"

# List of Debian suites.
DEBIAN_SUITES=($TESTING_CODENAME $STABLE_CODENAME
"testing" "stable")

# List of Ubuntu suites. Update these when needed.
UBUNTU_SUITES=("trusty" "xenial")

# Mirrors to use. Update these to your preferred mirror.
DEBIAN_MIRROR="mirror.switch.ch/ftp/mirror"
UBUNTU_MIRROR="mirror.switch.ch/ftp/mirror"

# Optionally use the changelog of a package to determine the suite to use if
# none set.
if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then
DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}')
# Use the unstable suite for certain suite values.
if $(echo "experimental UNRELEASED" | grep -q $DIST); then
DIST="$UNSTABLE_CODENAME"
fi
fi

# Optionally set a default distribution if none is used. Note that you can set
# your own default (i.e. ${DIST:="unstable"}).
: ${DIST:="$(lsb_release --short --codename)"}

# Optionally change Debian release states in $DIST to their names.
case "$DIST" in
unstable)
DIST="$UNSTABLE_CODENAME"
;;
testing)
DIST="$TESTING_CODENAME"
;;
stable)
DIST="$STABLE_CODENAME"
;;
esac

# Optionally set the architecture to the host architecture if none set. Note
# that you can set your own default (i.e. ${ARCH:="i386"}).
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
NAME="$NAME-$ARCH"
DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder
# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/aptcache/$NAME/"
BUILDPLACE="/var/cache/pbuilder/build/"

if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
# Debian configuration
MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
COMPONENTS="main contrib non-free"
# This is for enabling backports for the Debian stable suite.
#if $(echo "$STABLE_CODENAME stable" | grep -q $DIST); then
# EXTRAPACKAGES="$EXTRAPACKAGES debian-backports-keyring"
# OTHERMIRROR="$OTHERMIRROR | deb http://www.backports.org/debian $STABLE_BACKPORTS_SUITE $COMPONENTS"
#fi
elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
# Ubuntu configuration
MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
COMPONENTS="main restricted universe multiverse"
else
echo "Unknown distribution: $DIST"
exit 1
fi

Now we need to initialize the “Packages” file for the empty repo so we can work the first time:

dpkg-scanpackages /var/cache/pbuilder/repo > /var/cache/pbuilder/repo/Packages

(OPTIONAL, not yet tested) If you have lots of RAM (more than 4 GB) putting the pbuilder “build” chroot on tmpfs will speed it up immensely. so add the following to /etc/fstab (it should be all on one line starting with “tmpfs” and ending with the second zero).

tmpfs   /var/cache/pbuilder/build       tmpfs   defaults,size=2400M 0 0
and then mount it with "sudo mount /var/cache/pbuilder/build"

Now we need to initialize the pbuilder images for each OS variant, run the following command:

for arch in `echo i386 amd64` ; do for dist in `echo sid jessie trusty xenial` ; do sudo DIST=${dist} ARCH=${arch} pbuilder --create --architecture ${arch} --distribution ${dist} ; done ; done |tee /tmp/baseimage_create.log

Or only for trusty amd64 run:

sudo DIST=trusty ARCH=amd64 pbuilder --create --architecture amd64 --distribution trusty

To update the distroots to current patches run:

for arch in `echo i386 amd64` ; do for dist in `echo sid jessie trusty xenial` ; do sudo DIST=${dist} ARCH=${arch} pbuilder --update ; done ; done |tee /tmp/baseimage_update.log

Or only for trusty amd64 run:

sudo DIST=trusty ARCH=amd64 pbuilder --update

Prepare Package

This section explains the necessary steps to build a debian package afterwards.

Create orig.tar.xz Archive (without debian folder)

Inside the package (same level as the CMakeLists.txt file), run (with the appropriate excludes…):

tar -cJ --exclude-vcs --exclude='./.idea' --exclude='./debian' --exclude='./cmake-build-debug' -f ../libxsensmt_4.2.orig.tar.xz .

Use dh_make

Inside the package (same level as the CMakeLists.txt file), run:

dh_make -s -p ros-indigo-variant-msgs_0.1.3 --createorig

  * -s: single package
  * -p: enter the final ROS package name following the version number _x.x.x
  * --createorig: will create ros-indigo-variant-msgs_0.1.3.orig.tar.xz in /..

Inside the newly created debian folder you can delete some files:

cd debian
rm *.ex
rm *.EX
rm README.*
rm docs

Edit changelog should then look something like this:

ros-indigo-variant-msgs (0.1.3-1~trusty0) trusty; urgency=low

  * new release

 -- Leggedrobotics RSL (APT) <leggedrobotics@gmail.com>  Wed, 28 Dec 2016 09:53:48 +0100

trusty0 means

Edit rules, for ROS packages this should then look something like this (replace the the package name ros-indigo-variant-msgs with your package name):

#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.

# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
export DH_OPTIONS=-v --buildsystem=cmake
# TODO: remove the LDFLAGS override.  It's here to avoid esoteric problems
# of this sort:
#  https://code.ros.org/trac/ros/ticket/2977
#  https://code.ros.org/trac/ros/ticket/3842
export LDFLAGS=
export PKG_CONFIG_PATH=/opt/ros/indigo/lib/pkgconfig
# Explicitly enable -DNDEBUG, see:
#   https://github.com/ros-infrastructure/bloom/issues/327
export DEB_CXXFLAGS_MAINT_APPEND=-DNDEBUG

%:
    dh  $@

override_dh_auto_configure:
    # In case we're installing to a non-standard location, look for a setup.sh
    # in the install tree that was dropped by catkin, and source it.  It will
    # set things like CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
    if [ -f "/opt/ros/indigo/setup.sh" ]; then . "/opt/ros/indigo/setup.sh"; fi && \
    dh_auto_configure -- \
        -DCATKIN_BUILD_BINARY_PACKAGE="1" \
        -DCMAKE_INSTALL_PREFIX="/opt/ros/indigo" \
        -DCMAKE_PREFIX_PATH="/opt/ros/indigo"

override_dh_auto_build:
    # In case we're installing to a non-standard location, look for a setup.sh
    # in the install tree that was dropped by catkin, and source it.  It will
    # set things like CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
    if [ -f "/opt/ros/indigo/setup.sh" ]; then . "/opt/ros/indigo/setup.sh"; fi && \
    dh_auto_build

override_dh_auto_test:
    # In case we're installing to a non-standard location, look for a setup.sh
    # in the install tree that was dropped by catkin, and source it.  It will
    # set things like CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
    echo -- Running tests. Even if one of them fails the build is not canceled.
    if [ -f "/opt/ros/indigo/setup.sh" ]; then . "/opt/ros/indigo/setup.sh"; fi && \
    dh_auto_test || true

override_dh_shlibdeps:
    # In case we're installing to a non-standard location, look for a setup.sh
    # in the install tree that was dropped by catkin, and source it.  It will
    # set things like CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
    if [ -f "/opt/ros/indigo/setup.sh" ]; then . "/opt/ros/indigo/setup.sh"; fi && \
    dh_shlibdeps -l$(CURDIR)/debian/ros-indigo-variant-msgs//opt/ros/indigo/lib/

override_dh_auto_install:
    # In case we're installing to a non-standard location, look for a setup.sh
    # in the install tree that was dropped by catkin, and source it.  It will
    # set things like CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
    if [ -f "/opt/ros/indigo/setup.sh" ]; then . "/opt/ros/indigo/setup.sh"; fi && \
    dh_auto_install

Edit control, and add the dependencies listed in your package.xml. For ROS packages add the prefix ros-indigo-, for other rosdeps add the specific package name NOT the rosdep key (lookup table here: rosdep list e.g. key libqwt6 becomes libqwt-dev for trusty). Add the build-dependencies at Build-Depends and run-dependencies at Depends. For ros-indigo-variant-msgs the control file looks like that:

Source: ros-indigo-variant-msgs
Section: misc
Priority: extra
Maintainer: John Doe <john.doe@gmail.com>
Build-Depends: debhelper (>= 9.0.0), ros-indigo-catkin, ros-indigo-message-generation, ros-indigo-std-msgs
Homepage: http://github.com/ethz-asl/variant
Standards-Version: 3.9.2

Package: ros-indigo-variant-msgs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ros-indigo-message-runtime, ros-indigo-std-msgs
Description: Variant messages are designed to accommodate the information content of any invariant message.
 They are truly generic and can freely be converted to and from specific message objects.

Build Package

Inside the package (same level as the debian directory is located), run the following commands.

To build a package for e.g. trusty amd64 run:

pdebuild --architecture amd64 --buildresult ~/pbuilder_ws/packages --pbuilderroot "sudo DIST=trusty ARCH=amd64"

To build packages for multiple distributions, architectures run e.g.: Careful, you probably need different changelog and control files for different distributions.

pdebuild --architecture <i386|amd64> --buildresult /tmp --pbuilderroot "sudo DIST=<sid|jessie|trusty|xenial> ARCH=<i386|amd64>"

Rebuild Launchpad Debian Package (e.g. Backport)

Get Launchpad Sources

dget https://launchpad.net/ubuntu/+archive/primary/+files/google-glog_0.3.4-0.1.dsc

Prepare and Upload Package

  1. Unzip google-glog_0.3.4-0.1.debian.tar.xz
  2. Unzip google-glog_0.3.4.orig.tar.gz
  3. Structure:
    • tmp
      • glog-0.3.4
        • debian
      • google-glog_0.3.4.orig.tar.gz
  4. cd tmp/glog-0.3.4
  5. run sudo debuild -S -kE35F12BA (public launchpad gpg key id, gpg –list-keys)
  6. cd ..
  7. dput ppa:john-doe/google-glog google-glog_0.3.4-0trusty_source.changes

Debuild Options

Build source package (required for Launchpad)

sudo debuild -S

Do not sign package

-us    Do not sign the source package.
-uc    Do not sign the .changes file.
-S     Source-only package
-b     Binary-only package
-sa    Forces the inclusion of the original source.

Sign package after

debsign -k E35F12BA *.dsc
debsign -k E35F12BA *.changes

Sign debian package

debsigs --sign=origin -k E35F12BA libgoogle-glog-dev_0.3.4-0trusty_amd64.deb

debsigs Manpage

Debian Package

pdebuild --architecture amd64 --buildresult ~/pbuilder_ws/ws/glog/tmp/ --pbuilderroot "sudo DIST=trusty ARCH=amd64"