This is a simplified transcription of the AskUbuntu Classroom session of Packaging http://chat.stackexchange.com/transcript/message/1312879#1312879

This Classroom session was awesome :D.Although i had to be awake till 1:00AM 😛
This Session was brought to us by our extremely caffeinated friend The Evil Phoenix.

This session will cover the basics of creating .deb packages for Ubuntu installations.

Firstly, I would like to point out that during this session, we will be using the Command Line for most of the commands.

And before we continue, I must point out that during the session, there may be demonstrations of commands and actions.

The demonstrations will be using a file that is available via one of my servers:kor.trekweb.org/packaging/class-files.zip

This contains a basic file that will be used to create the demonstration package.

You will need to download and extract the files within the ZIP

Where you unzip the file to is irrelevant, but make it readily available.

Prerequisites for Packaging

In order to be able to create a package, it is recommended that users have a firm grasp of basic command line syntax as well as commands.

I’m going to assume that most of you have experience with the Terminal and Command-Line, however I will outline all commands as we go.

You must have a PGP key for yourself so that you may sign the .deb installer when you build it for deployment.

As this is a prerequisite, I will go briefly into how to create a PGP key via the GUI, using seahorse which ships standard with Ubuntu 11.04 (GNOME).
1) We will go through the easiest method of creating a PGP key via the GUI. It can be done via the command line, but the easiest method is the GUI.

First, you will need to run the Seahorse program. If you are using Unity, please open up the applications window, and type in “seahorse”. An icon will show up that says “Passwords and Encryption keys”. An easier method to open could be Alt + F2 (or in the terminal), then running seahorse

When you are in the GUI interface for seahorse, you will need to use the menu bar. Click “File” > “New”.

A screen like this one will show up:

user image

Select PGP Key, and hit continue.

The next screen will be similar to this:

user image

Provide a name and an email address for the key, and hit “Create”. A comment is not required, but may help you to differentiate between keys when you have several

The system will prompt you for a passphrase for the key.

It is strongly recommended you provide one.

After the key has been created, it will show up in the main window for Seahorse.

For this demonstration, you will not need to upload your PGP key to a key server.

However, if you were going to distribute your Debian packages, you would need to upload the PGP key to a key server, which I will very briefly explain here

Select the PGP key you created in the main seahorse window (the key should be under “personal keys”).

Go to the menu bar, choose “Edit”, and then “Preferences”.

Under the Key Servers tab, it will look similar to this:

user image

Make sure that under “Publish Keys” you select the Ubuntu keyserver entry.

close the preferences window, then, with your PGP key selected, go to the menu bar: “Remote” > “Sync and Publish Keys…”

click the “Sync” button.

Your PGP key will be uploaded to the Ubuntu keyservers, and will be available within a few minutes on the internet.

Now we will install all required software.

This command will run the installation of all required software for packaging:
sudo apt-get install build-essential devscripts ubuntu-       dev-tools debhelper dh-make diff patch cdbs quilt gnupg       fakeroot lintian pbuilder piuparts

A large number of packages will be installed and downloaded to your system for this.

Installation may take anywhere from 5 minutes to 30 minutes depending on various factors such as internet speed, system speeds, and other factors that contribute to a computer’s speeds.

One of the packages needed within that command, however, is postfix. You can choose “Local configuration” when it asks you for what config to use.
After all the packages are installed, we will need to create the pbuilder environment. pbuilder is the “Personal Builder”. It is used to build your packages after you’ve created the source package. This way, you can build the actual .deb in a chrooted environment.

Typically, you will be building the pbuilder build environment for the same distribution you are running, however you may also build environments for other distributions (Lucid, Maverick, etc).

This command will build the pbuilder environment for your distribution: sudo pbuilder create --distribution $(lsb_release -cs) --othermirror "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs) main restricted universe multiverse"

The creation of the pbuilder environment will take time.

On this system that I am using, pbuilder creation of the base environment for Natty took approximately 10 minutes; on my netbook (running Maverick), it took 20 minutes.

During this time, we can continue to build the core of the package without actually compiling the files into a .deb.

While pbuilder builds in one terminal window, please open another terminal window.

In that window, please navigate to the location where you unzipped the class-files.zip file.

In this ZIP file, you will see only one folder: exec

This folder contains the executable .sh script that will be made into a package and subsequently installed into the system for use.

In my system, I unzipped the file on the Desktop, and named the folder packaging-demo-1.0

you may name it what you wish, but I recommend you name the folder the same as I name it for congruency between commands.

In the Terminal, you should navigate to the path to that folder: cd /path/to/packaging-demo-1.0

Within that folder, we will begin creating the Debian control files which steer the creation of the package.
edit your `.bashrc`, and append this at the end:
export DEBFULLNAME=”Name provided in PGP Key
export DEBEMAIL=”Email provided in PGP Key

The command we will now run is: dh_make --createorig

$ dh_make --createorig

Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch?
 [s/i/m/l/k/n]

This is the output of the command when first run.

We will be choosing “single binary” as the option

 [s/i/m/l/k/n] s

Maintainer name : IGPF.us
Email-Address	: admin@igpf.us
Date				: Sat, 09 Jul 2011 14:38:16 -0400
Package Name	 : packaging-demo
Version			: 1.0
License			: blank
Type of Package : Single
Hit <enter> to confirm:

The information here was gathered from your PGP key.

in this case, my folder that I unzipped was renamed to be packaging-demo-1.0, which means the package name would be packaging-demo

if you used the original directory name, it will be packaging-test.
Press Enter
This will likely show up:

Currently there is no top level Makefile. This may require additional tuning.
Done. Please edit the files in the debian/ subdirectory now. You should also
check that the packaging-demo Makefiles install into $DESTDIR and not in / .
When packaging programs, you would usually create a Makefile which would dictate the destination of where things would be written.

we are going to use a different method for defining installation parameters for files.

via a debian control file called install

After dh_make has been run, run ls on the directory in terminal.

$ ls
total 16K
4.0K drwxr-xr-x 4 teward teward 4.0K 2011-07-09 14:46 ./
4.0K drwxr-xr-x 8 teward teward 4.0K 2011-07-09 14:46 ../
4.0K drwxr-xr-x 3 teward teward 4.0K 2011-07-09 14:46 debian/
4.0K drwxr-xr-x 2 teward teward 4.0K 2011-07-09 14:34 exec/

You can ignore the user fields, but as you can see, there is now a debian folder

Navigate into that folder.

You will notice many example files (*.ex files)

those were built in the event that you need to use them.

in this demo, we will not need them.

you may run the command rm *.ex *.EX to remove these files.

What is left should be similar to this:
$ ls
total 40K
4.0K drwxr-xr-x 3 teward teward 4.0K 2011-07-09 14:51 ./
4.0K drwxr-xr-x 4 teward teward 4.0K 2011-07-09 14:46 ../
4.0K -rw-r--r-- 1 teward teward  182 2011-07-09 14:46 changelog
4.0K -rw-r--r-- 1 teward teward    2 2011-07-09 14:46 compat
4.0K -rw-r--r-- 1 teward teward  533 2011-07-09 14:46 control
4.0K -rw-r--r-- 1 teward teward 1.5K 2011-07-09 14:46 copyright
   0 -rw-r--r-- 1 teward teward    0 2011-07-09 14:46 docs
4.0K -rw-r--r-- 1 teward teward  183 2011-07-09 14:46 README.Debian

(see full text)

I will give a brief explanation of these items, however these items are fully detailed in the Packaging Guide on the Ubuntu Wiki: wiki.ubuntu.com/PackagingGuide/Complete
The changelog file is exactly that: a log of changes between versions.

We will need to edit the changelog

Using nanovi, or your favorite CLI text editor, open the changelog file.

This is the changelog generated on my system:

packaging-demo (1.0-1) unstable; urgency=low

  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>

 -- IGPF.us <admin@igpf.us>  Sat, 09 Jul 2011 14:46:41 -0400

Replace where it says unstable with your distribution version (in my case, natty)

if you are using Lucid Lynx (10.04), put lucid; for Maverick, maverick; for Oneric, oneric

You may edit the * Initial release line to say whatever, but for this demo, replace it with * Packaging Demonstration

keep the initial two spaces before the *

Unfortunately, you cannot specify multiple versions in one changelog.

You would need to build the package multiple times, each time using a different distribution name

However, we will cover a method that allows you to use the PPA system of Launchpad to copy this one installer to other distributions. This will be covered in the second session, and not now.

After editing the changelog file, please save it.

The compat file we can ignore, but it is needed in order to identify compatibility levels with the various parts of building the .deb.

the control file is next, and we will need to edit it

Source: packaging-demo
Section: unknown
Priority: extra
Maintainer: IGPF.us <admin@igpf.us>
Build-Depends: debhelper (>= 7.0.50~)
Standards-Version: 3.9.1
Homepage: <insert the upstream URL, if relevant>
#Vcs-Git: git://git.debian.org/collab-maint/packaging-demo.git
#Vcs-Browser: git.debian.org/?p=collab-maint/packaging-demo.git;a=summary

Package: packaging-demo
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description>
 <insert long description, indented with spaces>

(see full text)

This is the control file that was generated within my system.

The commented lines for #Vcs-Git and #Vcs-Browser are unnecessary and may be removed.

This package is not connected to a home page, so that line is irrelevant today, however for a full project, you would put the URL to the project’s home page (even if its a Launchpad project) in for that line.

You’ll notice the Section: unknown line.

This determines what section the package is listed under in package managers

examples are net, utils, and others.

In this case, it doesnt really matter what we put (as long as its a valid section), and in this case we can putmisc

which stands for miscellaneous packages

Priority stands for the importance of the package.

This excerpt from the Packaging Guide sums it up:

Priority: This sets the importance of the package to users. It should be one of the following:Required – packages that are essential for the system to work properly. If they are removed it is highly likely that your system will break in an unrecoverable way.

Important – minimal set of packages for a usable system. Removing these packages will not produce an unrecoverable breakage of your system, but they are generally considered important tools without which any Linux installation would be incomplete. Note: This does not include things like Emacs or even the X Window System.

(see full text)

please expand to the full text of that line, there are more than just Required and Important.

We are going to leave our Priority as extra

because this is a specialized package that doesn’t fall into any of the other established groups.

the Source and Package lines should remain the same. This denotes the name of the package and its source equivalent

The Architecture line determines whether this package is platform-dependent

This list explains the various possible inputs:

all – The source is not architecture-dependent. Programs that use Python or other interpreted languages would use this. The resulting binary package would end with _all.deb.any – The source is architecture-dependent and should compile on all the supported architectures. There will be a .deb file for each architecture (_i386.deb for instance)

Format: http://dep.debian.net/deps/dep5
Upstream-Name: packaging-demo
Source: <url://example.com>

Files: *
Copyright: <years> <put author's name and email here>
           <years> <likewise for another author>
License: <special license>
 <Put the license of the package here indented by 1 space>
 <This follows the format of Description: lines in control file>
 .
 <Including paragraphs>

# If you want to use GPL v2 or later for the /debian/* files use
# the following clauses, or change it to suit. Delete these two lines
Files: debian/*
Copyright: 2011 IGPF.us <admin@igpf.us>
License: GPL-2+
 This package is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 .

In our case, as this is using a .sh file, there is no dependency for architecture, so we will use all for the Architecture line.

Replace Description: <insert up to 60 chars description> with Description: Demo Package, and replace ` <insert long description, indented with spaces>` with ` Demo Package`, keeping the space in front of it.

The first description line is a short description of the package.

the long description line can be paragraphs long of information.

This is one of the most important lines:

Depends: ${shlibs:Depends}, ${misc:Depends}

This defines any dependencies for the package.

For example, if you are packaging a python program and you require Python of version 2.6 or newer, you’d likely want to define that: Depends: python (>= 2.6)

However, as this is a Bash script, we really only need to worry about bash being installed.

use this for the line: Depends: ${shlibs:Depends}, ${misc:Depends}, bash

the last of the premade files we need to worry about is copyright

This details the copyright information for the package.

Format: dep.debian.net/deps/dep5
Upstream-Name: packaging-demo
Source: <url://example.com>

Files: *
Copyright: <years> <put author's name and email here>
           <years> <likewise for another author>
License: <special license>
 <Put the license of the package here indented by 1 space>
 <This follows the format of Description: lines in control file>
 .
 <Including paragraphs>

# If you want to use GPL v2 or later for the /debian/* files use
# the following clauses, or change it to suit. Delete these two lines

(see full text)

shlibs:Depends calculates any dependencies for any dependent packages you specified in Depends:. In this case, any dependent files for bash would be installed at the same time.

misc:Depends are miscellaneous dependencies that may or may not be needed

In any case, you do not need to have them

however, the shlibs:Dependsarea is strongly recommended

there are manpages for the shlibs:Depends one: man dh_makeshlibs
This is my copyright file after running dh_make
Format: http://dep.debian.net/deps/dep5
Upstream-Name: packaging-demo
Source: <url://example.com>

Files: *
Copyright: 2011 <yourinfo>

License: GPL-2+
 This package is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 .
 This package is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 .
 You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>
 .
 On Debian systems, the complete text of the GNU General
 Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.

# If you want to use GPL v2 or later for the /debian/* files use
# the following clauses, or change it to suit. Delete these two lines
Files: debian/*
Copyright: 2011 IGPF.us <admin@igpf.us>
License: GPL-2+
 This package is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 .
 This package is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 .
 You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>
 .
 On Debian systems, the complete text of the GNU General
 Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.

Where it says Source:, put any URL there

and where it says <yourinfo>, replace that with Your Name <email>

putting in your name and email

as matched on the PGP key

we are going to ignore the other files for now

and since i’m short on time, I will not answer any questions until the end of the session.

We must make one last file here: install

run the following command: touch install

then open up the new file

In here, we define were files go.

In this case, please put the following in: /exec/helloworld.sh /usr/bin

This will tell the installer to place the helloworld.sh file into /usr/bin

IN the install file, you will specify the location of where to place every file you included in the package.

with the exception of the Debian files

after you’ve done this, run cd ..

I’m going to skip the pbuilder demo, and instead point out the basic debuild system.

Run the following: debuild

This will build the .deb file
is it will build the debian installer (package).

it will ask for the keyphrase for the PGP key you used.

After which you can ls the parent directory of the folder you used for packaging and find all the created files and the .deb installer

You may test the installer by running /usr/bin/helloworld.sh

if it installed and works, you’ve done the package

I am now finished with the base tutorial of packaging.

Leave a comment