Menu
IRC Meeting Minutes
Projects
Articles
Notes |
This tutorial is based on the live tutorial given by Gürkan Sengün on the #debian-women irc channel. It has been slightly modified to fit the web style, and keep the names of the participants annonymous.
Introduction
This course is intended for people who have never made a debian package, but compiled some software from source themselves. We will create a little debian package. For this we'll need some debian tools, please do:
apt-get install build-essential devscripts dh-make
You can package anything that is Free Software (that complies to the DFSG (http://www.debian.org/social_contract)) for Debian (main). Before you package something for Debian, it is good idea to check if nobody else did it before, a quick search on google, and then a search to find if there's an [|ITP] on: http://www.debian.org/devel/wnpp/being_packaged. Once you are sure that the software is not packaged, then you should file an ITP yourself.
Anybody can work on Debian. People that make packages for Debian of software, can put it online (on a webserver). If that person then finds a sponsor (someone (a Debian Developer, short DD) who checks and uploads that package to debian), the person becomes a Debian Maintainer (DM) and appears at: http://www.debian.org/devel/people
When a new package is uploaded to Debian, it first appears in the "Debian new queue" (you can find that using google). Later it appears on http://buildd.debian.org
Getting the software
This tutorial will be given on the package wmplopfork (a little dockapp, that'll show cpu usage graphically), but the steps to be taken and the general advice given, apply to any other program.
You can download the software used in this tutorial from: http://hules.free.fr/wmforkplop/
A good idea when you are making packages is to have a directory called "debian" in your $HOME (or maybe "sources/debian" or "src/debian", you get the idea), and in that directory download the source code of the upstream programs.
So, once you have downloaded the source code, you should unpack it (in this case with tar -xzvf wmforkplop-0.9.1.tar.gz ). As you can see, wmforkplop unpacks nicely into wmforkplop-0.9.1, but not every software is available so nicely, sometimes they screw up and unpack in the same directory. You can have a look at the tar file by doing tar -tvf tarfile.tar.gz, or using mc.
Debianization
In your login script (.bashrc, .zshenv, etc) define the environment variables: export DEBEMAIL=your@email.address and export DEBFULLNAME="Your name". Be sure you have those variables exported before going on, they'll be used by dh_make.
Now it's the time to change into the new directory and execute dh_make. This program will ask some questions and help us in creating the new package.
Type of package: single binary, multiple binary, library, or kernel module? [s/m/l/k]
It's asking us what type of package we want to create. Select "s" for single binary. It's the usual package when you are starting. It's better to start simple, and then do more complicated packages when you are more experienced.
It'll show us some more information, and wait for <enter> to confirm, confirm it.
Preparing the package
dh_make does a very nice job of helping us start with the package, but there's still a lot of work to do, specially inside the debian/ directory.
A good practice is to now go and read the README and INSTALL files provided with the upstream package. This will allow us to know how the program is to be installed, and know if it has any unexpected dependencies. Also, if the INSTALL file is not the vanilla [|autotools], we might need to read it in detail to find out what we should to install it.
In the case of wmforkplop, the README tells us what other software we need to be able to build it: imlib2 and libgtop2; there is also a note that the source package has a font: Vera.ttf, since this is a font that is provided by another package (you can check that using http://packages.debian.org) we will depend on that package.
The INSTALL tells us that wmforkplop uses autotools, and therefore no Makefile needs to be touched. In the case of a piece of software that does not use the autotools, you might need to modify the Makefile in order to make it suitable for Debian. You need it to install into the debian/ directory by using $(DESTDIR).
Change into the debian/ directory and have a look at the many files that dh_make created, we'll be deleting a lot of them soon. Many of them are .ex files (from example), no .ex files should be left when you are finished packaging.
Since our software is not a daemon we can remove init.d.ex, and it's nothing todo with emacs, we can also just remove emacsen*. We don't need the post*.ex and pre*.ex. Also remove cron.d.ex, and manpage.*ml.ex (but not manpage.1.ex, since we'll be using that one). And also remove wmforkplop*, and conffile.ex since there are no conffiles.
Since we don't have notes we want to tell our users (yet), we can also remove README.Debian. After all this deleting, you should be left with 10 files.
We'll go through the remaining files in order.
:debian/changelog:In this file you see the package, the version-debian version archive and urgency, something like wmforkplop (0.9.1-1) unstable; urgency=low. Where 0.9.1 is the version of the program, and -1 is the debian revision, unstable is the archive we would be uploading to, and the urgency=low states how much time the package will spend in unstable before it's intended to migrate to testing (low means 10 days), you will usually want the "low" value, although "medium" and "high" are also available.
If we had filed an ITP, we'd have gotten a bugs.debian.org ITP bug number, something like #123456. We can close the bug with the upload of that package, if we put after * Initial Release. (Closes: #123456) into the changelog.
The debian/changelog file may seem innocent, but it's one of the most important ones. It's parsed by many bots (the bugs bot, the buildd bot, etc); it's the only file where you state the version of the package; it's the information that will be stored with each release.
:debian/control:This file controls the source package name, the binary package name, into what section the package goes, who the maintainer is (we can also define co-maintainers here), and if the package replaces another, suggest and/or recommend other things, and define dependencies (source as well as binary).
The suggested Source name is usually alright, but Section: unknown we want to change. The possible sections are documented in: http://www.nl.debian.org/doc/debian-policy/ch-controlfields.html, we will pick x11 for wmforkplop.
Priority: optional is alright. You can look at other packages, using apt-cache show to find out what priorities they have. For example, apt-cache show bash.
After the Maintainer: you could make a new line that says: Uploaders: Some friend <some@mail.ru>, this would state who the co-maintainers are. It's important to notice that the Uploaders field is not shown while doing apt-cache show somepackage, but it will appear if you do apt-cache showsrc somepackage.
One of the most important fields is Build-Depends. This lists the packages that are needed in order to be able to build this package. For wmforkplop, we need to do apt-cache search libgtop dev, and we'll find: libgtop2-dev, that's what we want to add to the Build-Depends line. Also do apt-cache search imlib dev and then add libimlib2-dev to the Build-Depends line. Build-Depends: debhelper (>= 4.0.0), libgtop2-dev, libimlib2-dev, that's how it should look like. You might wonder, what the (>= 4.0.0) is for, that's called a versioned build dependency. Sometimes a software needs a new enough library to work properly (or at all), that's what that is good for.
The Standards-Version should say 3.6.1, because that is the latest policy version: dpkg -l debian-policy (if you have it installed, if not, you should).
The top part we edited is the Source package information, now comes the binary package name: Package: wmforkplop. That should be ok. The Architecture: any says the package shall be compiled on any architecture (i.e it will be built on i386, sparc, powerpc, alpha, etc). Sometimes we have data (graphics, sound) or shellscripts that don't need be compiled, we would then change it to all, since once it's built it's useful for all the architectures.
The binary Depends is meant to state which packages must be around when we run the software. We should add the font package here, the one that has the Vera.ttf file, we can find it by doing dpkg -S Vera.ttf: ttf-bitstream-vera. So, our line should be: Depends: ${shlibs:Depends}, ${misc:Depends}, ttf-bitstream-vera. The ${...} are substitutions, they are replaced by other values which are automatically calculated by other tools at build time, shlibs:Depends are automatically calculated library dependencies when you run dh_shlibdeps in the rules file, and misc:Depends is calculated by debhelper.
The first Description: line is the short description, from the next line on, it's the long description. The short description should give a basic idea of what the package is, following the sintax: [package] is a [short description]. The long description has to start a new sentence (i.e. it does NOT continue the short desc), you need to leave one space at the beginning of each line, and if you want to leave an empty line, you have to put a space followed by a dot there. For wmforkplop, a good short description would be: "dockapp displaying processes and forking activity", and a good long description would be: "Each time a new process is created, and each time another one dies, a spot light appears on the applet and evolves. wmforkplop also displays the top cpu consuming processes, just like wmtop. It also has a process browser (click in the applet to bring it), which gives more informations about each process, and ability to kill a specific process, or "killall" all process who have the same name."
You can find a finished control file at: http://www.linuks.mine.nu/people/debian-women/
:debian/copyright:In this file you should state the upstream author, the place where you downloaded the software, and the licence of the program. If the software is GPL you can put just a brief notice, that states that "on Debian GNU/Linux systems you can find the complete GPL licence in /usr/share/common-licences/GPL". But if it's not GPL (or BSD), you should include the full licence here. If some parts of the software are GPL and some are some other licence, then you should state those parts very clearly, and the paste the licence verbatim in the copyright file.
:debian/docs:This file includes the files that will be copied to /usr/share/doc/package when the package is installed. In the case of wmforkplop, we can remove the Vera.txt line since we already added the dependency. Then we should have a look at the ../{NEWS, README, TODO} files. If there are only install/compile instructions we don't want that for the user in the binary package, so we remove them as well. If there is important or interesting information in those files, then we leave them there.
:debian/manpage.1.ex:This is an example of a manpage. Our package does not include the needed manpage for the command, so we need to edit it. The binary, when compiled, is called wmforkplop, therefore we want to rename manpage.1.ex to wmforkplop.1, if you are asking yourself "why is it .1?", do man man. We will not go into the details of editing the manual page here, just change the SECTION to 1, and do as much editing as you feel like doing.
:debian/menu.ex:This is an example of a menu file for the menu package. Our package is a graphical tool, and we need a menu file. So we rename menu.ex to menu. It's possible to add icons to your applications. You can find the finished menu file at: http://www.linuks.mine.nu/people/debian-women/
:debian/watch.ex:This is an example watch file, it can be removed safely, although it's quite useful. You can use uscan to check if there's a new version upstream.
:debian/compat:This file states the compatibility level with debhelper. Debhelper has gone through numerous revisions, some of which break compatibility, you can use the compat number to specify the debhelper revision that your package needs or supports. We already stated that we require dehelper (>= 4.0.0), so compat should say 4. You might have an old package, that uses old debhelper syntax and might be compat 1, or compat 2. It's recommended to use the latest version, anyway.
:debian/manpages:This file states where the manpages are, but it was not created by debhelper, we need to create it ourselves. In the debian/ directory do: echo "debian/wmforkplop.1" > manpages, and you are done.
:debian/rules:This file is similar to a Makefile, it has rules to perform a variety of tasks. Debhelper has already filled it with many rules and tasks, some of them are commented out. Once you are done editing, no commented out lines should be there. This is to say, you should uncomment those that you need and delete those that you don't. Suggested Makefile reading:
At the very bottom of the file you'll find three commented commands: dh_perl, dh_python, dh_makeshlibs, you can remove them all, since we are not using perl, nor python, nor making shlibs. We can then remove: dh_installinfo, dh_cron, dh_init, dh_mime, dh_pam, dh_emacsen, dh_logrotate, dh_debconf and dh_install too, for the same reasons. We would use dh_debconf if we had some debconf questions to ask to the user, and dh_install is to copy files inside the temporary build directory, but we aren't doing any extra copying. But do uncomment dh_installmenu (since we do have a menu file).
Building the packages
We are almost done with the preparation of the package, the next big step is to build it. We will do it using the command debuild. If you don't have your GPG key ready, you can do debuild -us -uc to build the package without signing. But keep in mind that it is a good idea to have your GPG key ready when building packages. It might complain that you don't have the necessary build dependencies, if so, install them.
When you are building, you might face some errors like E: wmforkplop: description-contains-tabs or W: wmforkplop: description-starts-with-leading-spaces or W: wmforkplop: manpage-section-mismatch. This is common, so don't feel bad about it, fix the errors and then try building again.
Once you are finished building, you should go to your parent directory (the $HOME/debian one) and list the files in it. You should have a diff.gz, a .dsc and a orig.tar.gz file, these are the source package (yes, the source package is actually three files); and a .deb file that is the binary package. There are also the .build and .changes files, you can have a look at them.
Now you can run lintian on the package, to check that it's in a good state: lintian -Ivi wmforkplop_0.9.1-1_i386.deb (or whichever was the file that you built). It will probably show you a list of errors and warnings that you'll have to go correct and then rebuild the package
Once you've done fixing the .deb errors and warnings, you might run lintian over the .dsc file (this is to say, over the source package), or directly over the .changes file (which will run lintian over all the files listed there - useful if you have many binary packages).
Installing and Running
The last test of the package is to install it and run it. To install it you'd do dpkg -i wmforkplop_0.9.1-1_i386.deb, and after it's installed try the things you packaged: try man wmforkplop, try running wmforkplop, and test the program (run a find / and in wmforkplop select the largest blob, then say kill, then gently)
Sharing your package
Even if you don't put your package in Debian, you can still share it with others by putting it on your webserver/debian/ directory. For one example, look at: http://www.linuks.mine.nu/debian/, and take a look at the update script in that directory, it will help you create your own debian repository.
Questions & Answers
These are the questions and answers that were made during the irc session, hopefully they'll answer many of the usual questions that might come up when reading this tutorial.
[[#ITP]] What does 'ITP' mean and what is it for?
ITP means "Intend To Package". It's a special type of bug, that indicates that you (or someone else) intends to package a certain piece of software. The aim of ITPs is that no work is duplicated, so if someone is packaging a program that you want to package, you don't need to do it twice.
It is good practice to file an ITP (using reportbug or a mail client) before you package software. That will "ensure" that no work is wasted (that other people
package the same software like you, if they check the ITP database).
See http://www.nl.debian.org/devel/wnpp/ for more information.
[[#autotools]] What are the autotools? What's the `./configure` script?
The autotools are a set of utilities to help a program compile on any platform. The ./configure tries to detect the platform it's on, and genereates a Makefile to fit the environment, or gives up if it cannot.
It's really a blessing, in the old days, you had to edit the Makefile yourself, and if your platform wasn't mentioned in the Makefile, you had to guess the values to use to make the program compile. Often you had to edit the source a little as well.
How do I package non-compiling packages? (docs, webpages, shellscripts)
There's no tutorial on this, because of the miriad of possibilities, so many different types of non-compilation packages that it's hard to have a general story on them. But you can look at example packages, for example ttf-junicode (Architecture: all), or supertux (all and i386). Try apt-get source somepackage and have a look at how it is done.