Translation(s): none


This is a tutorial how to create a Debian package Debian Astro. The tutorial consists of three parts:

  1. Preparation

  2. Packaging
  3. Upload and advanced packaging


1. Preparation

Previous page

2. Packaging

File and git layout

All debian specific packaging is done within the debian subdirectory, which is created on the top directory of the original package. The content of the original package is not changed directly (exceptions see below).

The standard git layout for debian packaging consists of three branches:

Install upstream files

Debian needs to have the source tar file with a specific name. So, download the latest packages from pypi and link it to the appropriate file name:

$ pip3 download --no-deps --no-binary :all: drms
Collecting drms
  Using cached https://files.pythonhosted.org/packages/47/af/9b835a693d2dd15b6ee275feeae5d3021453b9fcfdfd75fbb93e84d46447/drms-0.5.6.tar.gz
  Saved ./drms-0.5.6.tar.gz
$ cd drms

Import all files into the git repository, creating the layout described above

$ gbp import-orig ../drms-0.5.6.tar.gz
What will be the source package name? [drms] 
What is the upstream version? [0.5.6] 
gbp:info: Importing '../drms-0.5.6.tar.gz' to branch 'upstream'...
gbp:info: Source package is drms
gbp:info: Upstream version is 0.5.6
gbp:info: Successfully imported version 0.5.6 of ../drms-0.5.6.tar.gz

The defaults are usually OK here.

Create the debian specific files

Create the directory debian for the Debian specific files:

$ mkdir debian

Static files

There is one file that shows the format of the debian source package: debian/source/format. It can be created the following way:

$ mkdir debian/source
$ echo "3.0 (quilt)" > debian/source/format

debian/control

debian/control is the main configuration file for the Debian package. It contains a section for the source, and one section for each binary package. The sections should be separated by an empty line.

First the section for the package source and build process. This defines, for example, the build dependencies (which need to be adjusted for your package):

Source: drms
Section: python
Priority: optional
Maintainer: Debian Astronomy Team <debian-astro-maintainers@lists.alioth.debian.org>
Uploaders: Ole Streicher <olebole@debian.org>
Build-Depends: debhelper-compat (= 12),
               dh-python,
               python3-all (>= 3.4),
               python3-numpy (>= 1.9.0),
               python3-pandas (>= 0.14.1),
               python3-pytest,
               python3-setuptools,
               python3-six (>= 1.8.0)
Standards-Version: 4.4.0
Homepage: https://github.com/sunpy/drms
Vcs-Git: https://salsa.debian.org/debian-astro-team/drms.git
Vcs-Browser: https://salsa.debian.org/debian-astro-team/drms

Then follow sections for each binary package. Since Python 2 is deprecated, we have will have one package for Python-3. Per policy, the Python-3 package with python3-:

Package: python3-drms
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends}
Description: Access HMI, AIA and MDI data with Python
 The drms module provides an easy-to-use Python interface for
 accessing HMI, AIA and MDI data with Python. It uses the publicly
 accessible Joint Science Operations Center (JSOC) server by default,
 but can also be used with local NetDRMS sites.

The common and Python dependencies are calculated automatically, so one just specifies ${misc:Depends} and ${python3:Depends} here. Other depenencies (which cannot be found automatically) can be added here manually.

The architecture is set to all, since the package is architecture independent (only byte code, no C-code). If the package contains C extensions that are compiled, replace all with any. This will build the package individually for each available Debian platform. In this case, one usually also needs to add the dependency ${shlibs:Depends}, which adds dependencies of the extension shared lib.

debian/copyright

Debian is quite strict when it comes to the freeness of your code. Only packages that follow the "Debian Free Software Guidelines" are accepted. That requires a very careful documentation of the copyright of the package.

drms is BSD licensed, so the debian/copyright starts with this:

Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/

Files: *
Copyright: 2014-2016, Kolja Glogowski and others.
License: Expat
 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.

However, you must carefully check that the copyright is actually correct! Look into each individual source file to check the copyright holder and if it may have a different license. Do not forget bundled third party libraries, documentation files or data files. If in doubt, contact upstream to get a clear answer. All files need to be documented here, even if they are not used for the package. For example, in drms there were two files with a different license. So, the following paragraph had to be added:

Files: doc/_themes/drmsdoc/static/drmsdoc.css doc/_static/copybutton.js
Copyright: 2016, Python Software Foundation
  2016, Kolja Glogowski
License: PSF
 PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
 --------------------------------------------
 .
 1. This LICENSE AGREEMENT is between the Python Software Foundation
 [...]

Clarifying the license is one of the major jobs when packaging, and probably the most annoying one. Don't be sloppy here: each package is re-checked by Debians ftp-masters when it is uploaded. If the ftp-masters are not convinced that everything is fine (and they are picky!), they will reject the package, causing a substantial delay to get the package into Debian.

debian/changelog

This file is used to document the changes during the lifetime of the packge. In the build process, it is used to retrieve the version and the revision of the package.

A template can be created with the command

$ dch --create --package drms -v 0.5.6-1

This will open your editor:

drms (0.5.6-1) unstable; urgency=low

  * Initial release (Closes: #XXXXXX)

 -- Ole Streicher <olebole@debian.org>  Thu, 21 Mar 2019 10:24:04 +0100

Replace the bug number by the number that was given to your ITP bug and save the file. For the first Debian package version, the changelog should just have this one entry.

The build scripts will take the version (0.5.6) and revision number (1) from here.

debian/watch

For packages hosted on pypi, the easiest way to get the watch file is via a specialized URL: http://pypi.debian.net/drms/watch This gives the following file:

version=4
opts=uversionmangle=s/(rc|a|b|c)/~$1/ \
http://pypi.debian.net/drms/drms-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))

debian/rules

This file contains the recipe to build the package. As for many other standard installation procedures, this is already builtin in the Debian tools. So this file is quite simple:

#!/usr/bin/make -f

export PYBUILD_NAME=drms

%:
        dh $@ --with python3 --buildsystem=pybuild

(Note that the last line is indented by tab, not by spaces, since this is a Makefile)

Finall, set the executable flag for debian/rules:

$ chmod a+x debian/rules

Before continuing, you should commit all changes to the master branch:

$ git add debian/
$ git commit -m "Initial Debian files"

debian/patches

Often there is a need to apply small patches to the original distribution. One example here is that it is discouraged to use embedded code copies of other software; instead the other software should be used as a Debian package.

The preferred way to add a patch is to create a separate git branch patch-queue/master with git-buildpackage:

$ gbp pq switch
gbp:info: No pq branch found, importing patches
gbp:info: Trying to apply patches at 'd1aa3b962f66a38870b4aeee29b43c448c88e5bb'
gbp:info: 0 patches listed in 'debian/patches/series' imported on 'patch-queue/master'
gbp:info: Switching to 'patch-queue/master'

Now you can edit and commit your changes with git. Each commit will end up as a separate patch, so it is useful to use `git rebase -i master` to re-organize them. After this is done, one can issue a

$ gbp pq export
gbp:info: On 'patch-queue/master', switching to 'master'
gbp:info: Generating patches from git (master..patch-queue/master)

This all will create a subdirectory debian/patches. This can be reviewed and committed then.

Summary listing of all debian files

This is the list of all files we created so far:

$ ls -lR debian/
ls -lR debian/
total 24
-rw-r--r-- 1 ole ole  151 Jun  8 18:06 changelog
-rw-r--r-- 1 ole ole 1705 Jun  8 18:05 control
-rw-r--r-- 1 ole ole 1834 Jun  8 18:05 copyright
drwxr-xr-x 1 ole ole   76 Jun  9 08:39 patches
-rwxr-xr-x 1 ole ole  230 Jun  8 18:07 rules
drwxr-xr-x 1 ole ole   12 Jun  8 18:04 source
-rw-r--r-- 1 ole ole  137 Jun  8 18:06 watch

debian/patches:
total 8
-rw-r--r-- 1 ole ole  33 Jun  9 08:39 series
-rw-r--r-- 1 ole ole 267 Jun  8 18:10 0001-Example.patch

debian/source:
total 4
-rw-r--r-- 1 ole ole 12 Jun  8 18:04 format

Build the package

Once you created all needed files, you are ready to start a first build. As mentioned before, the build process is done with the "pbuilder" program that creates a chrooted clean Debian environment.

If you did not update this environment for a while, do this now:

$ sudo pbuilder update

Then the command to create the package is simply

$ gbp buildpackage

Since the chroot needs root privilegues, you will be asked for your password.

Packaging will take some time, since the system is setup from scratch using only the packages the were specified as build dependencies. The build log is printed to the screen and also stored in the parent directory as ../drms_0.5.6-1_amd64.build.

If the build was successfull, the package files are created in /var/cache/pbuilder/result. These are:

If you have installed all requirements on your machine, you can now install the Debian packages with

$ sudo apt install /var/cache/pbuilder/result/python3-drms_0.5.6-1_all.deb

respectively

Lintian

Once your package builds completely, you should check it against a number of common mistakes. The main tool here is "lintian". Just run it with the .changes file as argument:

$ lintian /var/cache/pbuilder/result/drms_0.5.6-1_amd64.changes

All errors and warnings shown there should be fixed before the package can be uploaded. There are, however, sometimes false warnings, for example if some that way on (good) purpose, or just because of an outdated lintian. For example, in the case of wcsaxes, one would get the following warning:

W: python3-wcsaxes: image-file-in-usr-lib usr/lib/python3/dist-packages/wcsaxes/tests/baseline_images/update_clip_path_rectangular.png

If you don't understand the short message, you can just google it, or you specify the -i option; then lintian displays a longer explanation.

Lintian warnings that should be ignored on purpose, can be silenced by creating a file debian/<package>.lintian-overrides. Note that you must give the reason why you disabled the lintian message as a comment.

Lintian can do much more tests, so to create a good package it is highly recommended to run it with the arguments -E -I --pedantic as well:

$ lintian -E -I --pedantic /var/cache/pbuilder/result/drms_0.5.6-1_amd64.changes
P: drms source: debian-watch-may-check-gpg-signature

3. Upload and advanced packaging

Next page


See also

There is quite a lot documentation available that you can check for further information. The most important pages are

The policies describe the basic rules to follow when packaging:


CategoryPackaging