Building A Binary Deb Package

Building a binary Debian package for Ubuntu

Prerequisites

First some reading:

And then we need something to try and install: Create a dummy Java application

Ok, after this background we are ready to try our hand at building a binary Debian package…

Creating the folder structure for the .deb installer

Create the project root folder:

mkdir ~/tmp/cubanker

this will be the name that the package builder will use for your application name.

Now create the following folders in that directory which will be the folders on the system into which the installer will install files.

tmp/cubanker/etc/xdg/menus/applications-merged/
tmp/cubanker/usr/bin/
tmp/cubanker/usr/share/doc/
tmp/cubanker/usr/share/doc/cubanker/
tmp/cubanker/usr/share/desktop-directories/
tmp/cubanker/usr/share/man/
tmp/cubanker/usr/share/man/man1/
tmp/cubanker/usr/share/applications/
tmp/cubanker/usr/share/pixmaps/
tmp/cubanker/usr/lib/cubanker/
tmp/cubanker/DEBIAN/
tmp/cubanker/debian/

Don't worry about what all these folders are for just yet - it all becomes clear after 2 to 3 to 7 hours of mucking around…

Creating the control file for the .deb

A binary installer requires a control file in the DEBIAN directory. Although this will not be how we will be distributing cubanker as we will want to be distributing source, this entire exercise is one in understanding the essentials of installing an application on an Ubuntu system.

Here is the binary control file:

Package: cubanker
Version: 0.0.1
Section: web
Priority: optional
Architecture: i386
Maintainer: Bank Builder <info@communitybanker.org>
Description: This is a NUL installer for Community Banker
 .
 This NUL installer for Community Banker installs a do-nothing app and the documentation URLs for the project.
 .
 Contact info@communitybanker.org to assist this project

By now you would have seen in the recommended reading that the "." leaves a blank line in your long description.

Populating the folders

Working in our ~/tmp/cubanker folder we now can place the intended file(s) for installation.

  • usr/cubanker/Cuwiki.class - which we compiled previously Create a dummy Java application
  • usr/bin/cubanker.sh - the execution script we use for our Java terminal application

Here are the contents of cubanker.sh:

#!/bin/bash
clear
echo "************ Starting Application *************"
read -p "Push Enter to continue: "
cd /usr/lib/cubanker
java -cp . Cuwiki
echo "------------ Java App done --------------"
read -p "Push Enter to close terminal"

The remaining directories to populate are:
  • Man pages and documentation
    • ~/tmp/cubanker/usr/share/doc/cubanker/readme.txt - a simple txt file
    • ~/tmp/cubanker/usr/share/man/man1/cubanker.1.gz - see the section below on how to make man pages
  • Gnome Menu related files in the following directories - see the section below
    • ~/tmp/cubanker/usr/share/applications
    • ~/tmp/cubanker/usr/share/desktop-directories
    • ~/tmp/cubanker/usr/share/pixmap
    • ~/tmp/cubanker/etc/xdg/menus/applications-merged

Man pages

Creating man pages turns out to be easy but see unix_manual to get started. The compressed, numbered man pages need just be placed in the man/man1 etc directories and are available by the following once there:

>man cubanker

… resulting in the familiar (IMHO mostly useless) output:
cubanker()                                                          cubanker()

NAME
       cubanker.sh - starts the Community Banker server

SYNOPSIS
       cubanker.sh

DESCRIPTION
       cubanker.sh  runs  a script which starts the java services for a Commu‐
       nity Banker server. This is the core program along with  data  and  web
       services  and  which  requires  installation  as  per  the  wiki  bank-
       builders.wikidot.com

AUTHOR
       The bank-builders team.

                                                                    cubanker()
 Manual page cubanker(1) line 1/22 (END)

To create this single man page the following source page, called cubanker.1, was used:
.TH cubanker
.SH NAME
cubanker.sh - starts the Community Banker server
.SH SYNOPSIS
.B cubanker.sh
.SH DESCRIPTION
.I cubanker.sh
runs a script which starts the java services for 
a Community Banker server. This is the core program 
along with data and web services and which requires 
installation as per the wiki bank-builders.wikidot.com
.SH AUTHOR
The bank-builders team.

Since editing and compressing and copying it to the correct man/man1 path is a repetitive task you may find the following script which I kept in the ~/tmp folder along with the cubanker.1 man source page. The reason for this was that the path from cubanker/…. onwards was owned by root:root and the ~/tmp was owned by my user. Anyway, here is the script mkmanpg.sh:
#!/bin/bash
cp $1 $1.bak
gzip -9 $1
sudo cp $1.gz cubanker/usr/share/man/man1/.
cp $1.bak $1
rm $1.bak

and it is easy enough to use:
> ./mkmanpg.sh cubanker.1

GNOME Menus

It turns out that GNOME menus are tricky and yet straight forward. Essentially to get the application launcher into the menu system the following is needed:

  1. A [menu-item].desktop file(s) to be placed in ~/tmp/cubanker/usr/share/applications.
  2. A [sub-menu].directory file which defines the name and icon of a sub-menu which must be placed in ~/tmp/cubanker/usr/share/desktop-directories
  3. A [menu-merge-xml].menu which defines how the sub-menu(s) and menu-item(s) must be merged into the existing GNOME menu structure. This is placed in the ~/tmp/cubanker/etc/xdg/menus/applications-merged folder. Note that the Debian Policy Manual refers to a application-merged folder without the "s" which messed me up for quite some time!
  4. These all assume the presence of the referenced .png icons (46x46 is a good size) in ~/tmp/cubanker/usr/share/pixmap

The .desktop files

Each menu entry is similar to this one for community-banker-wiki.desktop :

[Desktop Entry]
Version=0.0.1
Name=Wiki Documentation
Comment=Community Banker Documentation
Exec=firefox http://bank-builders.wikidot.com/
Icon=community-banker-wiki
Terminal=false
Type=Application
StartupNotify=false
Categories=Application;CuBanker;

Note also that in Nautilus it appears with the Name listed inside the Desktop Entry of Wiki Documentation and of file type desktop configuration file. Notice that the icon does not need a path nor an extension if it is to be found in the pixmaps folder.

An .desktop entry for each of following is placed in the applications folder:

  • community-banker-branch.desktop
  • community-banker-call-centre.desktop
  • community-banker.desktop
  • community-banker-group.desktop
  • community-banker-home.desktop
  • community-banker-user.desktop
  • community-banker-wiki.desktop

For the execution of our cubanker.sh change the entries as follows:

Exec=/usr/bin/cubanker.sh
Terminal=true

The .directory file(s)

The appearance of the sub-menu we want to place in the Applications menu is governed by the community-banker.directory file we place in ~/tmp/cubanker/usr/share/applications:
[Desktop Entry]
Name=Community Banker
Icon=community-banker
Type=Directory
Comment=Community Banker Enterprise Applications

The .menu file(s)

The .menu file is used to merge our sub-menu and menu items into the desired GNOME menu. I found many examples were not clear that the menu structure represneted in XML must include the parent Applications menu to prevent your menu-items landing up in the undesirable Other menu.

Here is the community-banker.menu file which went into ~/tmp/cubanker/etc/xdg/menus/applications-merged :

<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
          "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
<Menu>
  <Name>Applications</Name>
         <!-- Community Banker -->
         <Menu>
            <Name>Community Banker</Name>
              <Directory>community-banker.directory</Directory>
              <Include>
                 <And>
                   <Category>CuBanker</Category>
                 </And>
                 <Filename>community-banker.desktop</Filename>
                 <Filename>community-banker-wiki.desktop</Filename>
                 <Filename>community-banker-group.desktop</Filename>
                 <Filename>community-banker-home.desktop</Filename>
                 <Filename>community-banker-call-centre.desktop</Filename>
                 <Filename>community-banker-user.desktop</Filename>
                 <Filename>community-banker-branch.desktop</Filename>
              </Include>
          </Menu>
          <!-- End Community Banker -->
</Menu>

The other secret for ensuring that the menu items appear under the correct sub-menu is the use of
<And>
   <Category>CuBanker</Category>
</And>

which must match the category in the .desktop file(s)
Categories=Application;CuBanker;

It was all a little like alchemy in the beginning but it seems to work now.

The Icons file(s)

To make life a bit easier I standardized the naming convention of my icons. These are simply copied into the folder as follows:

~/tmp/cubanker/usr/share/pixmaps/community-banker.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-branch.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-call-centre.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-groups.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-money.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-server.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-web.png
~/tmp/cubanker/usr/share/pixmaps/community-banker-wiki.png

Building the package

Since building the package was something that has to be done over and over as you tweak and fiddle and learn, the following script which I ran from the ~/tmp, aptly called doagain.sh was extremely useful:

#!/bin/sh
sudo rm *.deb
sudo dpkg --purge cubanker
sudo chown root:root -R cubanker
sudo dpkg --build cubanker cubanker-0.0.1.deb
sudo dpkg -i cubanker-0.0.1.deb

make it executable
chmod +x doagain.sh

… and it's output will look something like this:
andrew@bfg:~/tmp$ ./doagain.sh
(Reading database ... 103737 files and directories currently installed.)
Removing cubanker ...
dpkg-deb: building package `cubanker' in `cubanker-0.0.1.deb'.
Selecting previously deselected package cubanker.
(Reading database ... 103705 files and directories currently installed.)
Unpacking cubanker (from cubanker-0.0.1.deb) ...

but more importantly, it will have created the file cubanker-0.0.1.deb in the ~/tmp directory.

Linda

Linda was useful when my package was very broken.

Download the example

Download the entire tmp directory tmp.tar.gz

page_revision: 28, last_edited: 1251662820|%e %b %Y, %H:%M %Z (%O ago)