Requirements: build-essential, automake, gnupg, lintian, fakeroot and pbuilder.
In this example we will be using the GNU hello
program as our example. You can download the source tarball from
ftp.gnu.org.
For the purposes of this example, we will be using the
~/hello/
directory.
mkdir ~/hello cd ~/hello wget http://ftp.gnu.org/gnu/hello/hello-2.1.1.tar.gz
We will also compare our package to one that is already
packaged in the Ubuntu repository. For now, we will place
it in the ubuntu
directory so we can look at
it later. To get the source
package, make sure you have a "deb-src" line in your
/etc/apt/sources.list
file for the Main
repository. Then, simply execute:
mkdir ubuntu cd ubuntu apt-get source hello cd ..
Unlike most apt-get commands, you do not need to have root privileges to get the source package, because it is downloaded to the current directory. In fact, it is recommended that you only use apt-get source as a regular user, because then you can edit files in the source package without needing root privileges.
Was der apt-get source Befehlt bewirkt ist Folgendes:
Download the source package. A source package commonly contains a .dsc file describing the package and giving md5sums for the source package, an .orig.tar.gz file containing the source code from the author(s), and a .diff.gz file containing patches applied against the source code with the packaging information.
Entpacken sie die .orig.tar.gz Datei in das aktuelle Verzeichnis.
Apply the gunzipped .diff.gz to the unpacked source directory.
Wenn Sie manuell Quellpakete herunterladen (.dsc, .orig.tar.gz, and .diff.gz files),können Sie diese auf die gleiche Weise entpacken, wie es apt-get source tut, indem Sie dpkg-source wie folgt verwenden:
dpkg-source -x *.dsc
The first thing you will need to do is make a copy of the
original (sometimes called "upstream") tarball in the following
format:
<packagename>_<version>.orig.tar.gz
.
This step does two things. First, it creates two copies of the source
code. If you accidentally change or delete the working copy you can
use the one you downloaded. Second, it is considered poor
packaging practice to change the original source tarball unless
absolutely necessary. See „Häufige Fehler“ for
reasons.
cp hello-2.1.1.tar.gz hello_2.1.1.orig.tar.gz tar -xzvf hello_2.1.1.orig.tar.gz
Der Unterstrich "_" zwischen dem Paketnamen (hello) und der Versionsnummer (2.1.1), im Gegensatz zu einem Bindestrich "-", ist sehr wichtig. Ihr Quellpaket würde nicht richtig als ein natives Debain Paket kompiliert werden.
We now have a hello-2.1.1
directory
containing the source files. Now we need to create the customary
debian directory where all the
packaging information is stored, allowing us to separate the
packaging files from the application source files.
mkdir hello-2.1.1/debian cd hello-2.1.1/debian/
We now need to create the essential files for any Ubuntu
source package: changelog
,
control
, copyright
, and
rules
. These are the files needed to create
the binary packages (.deb files) from the original (upstream)
source code. Let us look at each one in turn.
The changelog
file is, as its name
implies, a listing of the changes made in each version. It
has a specific format that gives the package name, version,
distribution, changes, and who made the changes
at a given time. If you have a GPG key, make sure to use the same name
and email address in changelog
as you
have in your key. The following is a template
changelog
:
package (version) distribution; urgency=urgency * change details more change details * even more change details -- maintainer name <email address>[two spaces] date
Die Formatierung (vor allem die des Datums) ist wichtig. Das Datum sollte in dem RFC822 Format sein, welches über das Programm 822-date erlangt werden kann.
Hier ist eine Beispiel für eine changelog
Datei für das hello Programm:
hello (2.1.1-1) dapper; urgency=low * Ganz tolle neue Version mit 5 Kilo Bugfixes. -- Paket_Kapitän <packager@coolness.de> Sat, 22 Apr 2006 13:52:49 -0700
Notice that the version has a -1 appended to it, or what is called the Debian revision, which is used so that the packaging can be updated (to fix bugs for example) with new uploads within the same source release version.
Ubuntu and Debian have slightly different package versioning
schemes to avoid conflicting packages with the same
source version. If a Debian package has been changed in Ubuntu,
it has ubuntuX (where
X is the Ubuntu revision number)
appended to the end of the Debian version. So if the
Debian hello package was
changed by Ubuntu, the version string would be
2.1.1-1ubuntu1
. If a package for the
application does not exist in Debian, then the Ubuntu
version is 0
(e.g.,
2.1.1-0ubuntu1
).
Nun schauen Sie sich das changelog
für das Ubuntu Quellpaket an, die wir vorher heruntergeladen haben:
less ../../ubuntu/hello-2.1.1/debian/changelog
Notice that in this case the distribution is unstable (a Debian branch), because the Debian package has not been changed by Ubuntu. Remember to set the distribution to your target distribution release.
At this point create a changelog
file
in the debian
directory where you should
still be.
Die control Datei enthält die Informationen, die der Paketmanager (so wie zum Beispiel apt-get, synaptic, und aptitude) braucht: Abhängigkeiten, Hinweise zur Instandhaltung, und noch viel mehr.
For the Ubuntu hello package, the control file looks something like:
Source: hello Section: devel Priority: optional Maintainer: Paket_Kapitän <packager@coolness.de> Standards-Version: 3.6.1 Package: hello Architecture: any Depends: ${shlibs:Depends} Description: The classic greeting, and a good example The GNU hello program produces a familiar, friendly greeting. It allows non-programmers to use a classic computer science tool which would otherwise be unavailable to them.↵ . Seriously, though: this is an example of how to do a Debian package.↵ It is the Debian version of the GNU Project's `hello world' program (which is itself an example for the GNU Project).
Erstellen sie die control
Datei mit den Informationen von oben (stellen Sie sicher,dass Sie ihre Information in dem Maintainer - Feld eintragen).
Der erste Abschnitt gibt uns Informationen über das Quellpaket. Schauen wir uns jede Zeile einzeln einmal an:
Source: Das ist der Name des Quellpakets, in diesem Fall, hello.
Section: Die apt-Repositories sind in verschiedene Sektionen aufgeteilt um das Durchsuchen zu erleichtern: in unserem Fall wäre das: hello gehört in die devel Sektion.
Priority: Das setzt die Wichtigkeit des Paketes für die Benutzer fest. Es sollte eines von den folgenden sein:
Required - Ein Paket, das unabdingbar für das System ist, um richtig zu arbeiten. Wenn diese entfernt werden, ist die Wahrscheinlichkeit sehr hoch, dass ihr System irreperabel beschädigt wird.
Important - Die minimalen Pakete für ein brauchbares System. Entfernen dieser Pakete wird nicht zu einem schwerwiegenden Fehler führen, aber sie werden generell als wichtige Werkzeuge angesehen, ohne die jede Linux-Installation nicht komplett wäre. HINWEIS: Dazu zählen nicht Dinge wie Emacs oder sogar das X Window-System.
Standard - Eigentlich selbsterklärend.
Optional - Im Wesentlichen ist diese Kategorie für Pakete die nicht unbedingt gebraucht werden -- die meisten Pakete sind solche. Jedoch sollten sie nicht untereinander Kompatibilitätskonflikte verursachen.
Extra - Pakete, die mit anderen Paketen der oben genannten Kategorien Konflikte verursachen könnten. Wird auch für spezielle Pakete gebraucht, die nur für Leute nützlich sind, die schon wissen was der Zweck des Pakets ist.
Maintainer: The package maintainer with email address.
Standards-Version: The version of the Debian Policy to which the package adheres (in this case, version 3.6.1). An easy way to find the current version is apt-cache show debian-policy | grep Version.
Build-Depends: One of the
most important fields and often the source of bugs, this line
lists the binary packages (with versions if necessary)
that need to be installed in order to create the binary package(s)
from the source package. Packages that are essential are
required by build-essential and do not need to be
included in the Build-Depends line. In the case of
hello, all the needed packages are a
part of build-essential, so a Build-Depends line is not
needed. The list of build-essential packages can be found at
/usr/share/doc/build-essential/list
.
The second paragraph is for the binary package that will be built from the source. If multiple binary packages are built from the source package, there should be one section for each one. Again, let us go through each line:
Package: The name for the binary package. Many times for simple programs (such as hello), the source and binary packages' names are identical.
Architecture: The architectures for which the binary package(s) will be built. Examples are:
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)
A subset of architectures (i386, amd64, ppc, etc.) can be listed to indicate that the source is architecture-dependent and does not work for all architectures supported by Ubuntu.
Depends: The list of
packages that the binary package depends on for functionality. For
hello, we see
${shlibs:Depends}
, which is a variable that
substitutes in the needed shared libraries. See the
dpkg-source
man page for more
information.
Recommends: Used for packages that are highly recommended and usually are installed with the package. Some package managers, most notably aptitude, automatically install Recommended packages.
Suggests: Used for packages that are similar or useful when this package is installed.
Conflicts: Used for packages that will conflict with this package. Both cannot be installed at the same time. If one is being installed, the other will be removed.
Description: Both short and long descriptions are used by package managers. The format is:
Description: <single line synopsis> <extended description over several lines>
Note that there is one space at the beginning of each line in the long description. More information on how to make a good description can be found at http://people.debian.org/~walters/descriptions.html.
This file gives the copyright information. Generally, copyright information
is found in the COPYING
file in the program's source
directory. This file should include such information as the names of the
author and the packager, the URL from which the source came, a
Copyright line with the year and copyright holder, and the text of the
copyright itself. An example template would be:
This package was debianized by {Your Name} <your email address> {Date} It was downloaded from: {URL of webpage} Upstream Author(s): {Name(s) and email address(es) of author(s)} Copyright: Copyright (C) {Year(s)} by {Author(s)} {Email address(es)} License:
Wie man sich denken kann, wird hello unter der GPL Lizenz herausgegeben. In diesem Fall ist es das einfachste, einfach diecopyright
Datei aus dem Ubuntu Paket zu kopieren:
cp ../../ubuntu/hello-2.1.1/debian/copyright .
You must include the complete copyright unless it is is GPL, LGPL, BSD, or
Artistic License, in which case you can refer to the corresponding file in the
/usr/share/common-licenses/
directory.
Notice that the Ubuntu package's
copyright
includes a license statement for
the manual. It is important that all the
files in the source be covered by a license statement.
Die rules
Datei sit eine ausführbare Makefile die die Regeln enthält, um das Binärpaket von dem Quellpaket zu erstellen. Für hello wird es am Leichtesten sein, die rules
Datei von dem Ubuntu Paket zu verwenden:
#!/usr/bin/make -f # Sample debian/rules file - for GNU Hello. # Copyright 1994,1995 by Ian Jackson. # I hereby give you perpetual unlimited permission to copy, # modify and relicense this file, provided that you do not remove # my name from the file itself. (I assert my moral right of # paternity under the Copyright, Designs and Patents Act 1988.) # This file may have to be extensively modified package = hello docdir = debian/tmp/usr/share/doc/$(package) CC = gcc CFLAGS = -g -Wall INSTALL_PROGRAM = install ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif build: $(checkdir) ./configure --prefix=/usr $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" touch build clean: $(checkdir) rm -f build -$(MAKE) -i distclean rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars binary-indep: checkroot build $(checkdir) # There are no architecture-independent files to be uploaded # generated by this package. If there were any they would be # made here. binary-arch: checkroot build $(checkdir) rm -rf debian/tmp install -d debian/tmp/DEBIAN $(docdir) install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ prefix=$$(pwd)/debian/tmp/usr install cd debian/tmp && mv usr/info usr/man usr/share cp -a NEWS debian/copyright $(docdir) cp -a debian/changelog $(docdir)/changelog.Debian cp -a ChangeLog $(docdir)/changelog cd $(docdir) && gzip -9 changelog changelog.Debian gzip -r9 debian/tmp/usr/share/man gzip -9 debian/tmp/usr/share/info/* dpkg-shlibdeps debian/tmp/usr/bin/hello dpkg-gencontrol -isp chown -R root:root debian/tmp chmod -R u+w,go=rX debian/tmp dpkg --build debian/tmp .. define checkdir test -f src/$(package).c -a -f debian/rules endef binary: binary-indep binary-arch checkroot: $(checkdir) test $$(id -u) = 0 .PHONY: binary binary-arch binary-indep clean checkroot
Lasst uns diese Datei im Detail einmal anschauen. Eine der ersten Sachen die Sie bemerkt haben werden ist die Deklaration von einigen Variablen:
package = hello docdir = debian/tmp/usr/share/doc/$(package) CC = gcc CFLAGS = -g -Wall INSTALL_PROGRAM = install ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif
This section sets the CFLAGS for the compiler and also handles the
noopt
and nostrip
DEB_BUILD_OPTIONS for debugging.
Next is the build
rule:
build: $(checkdir) ./configure --prefix=/usr $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" touch build
This rule runs ./configure with the proper prefix,
runs make, and creates a build
file that is a timestamp of the
build to prevent erroneous multiple compilations.
The next rule is clean
, which runs make -i distclean
and removes the files that are made during the package building.
clean: $(checkdir) rm -f build -$(MAKE) -i distclean rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars
Next we see an empty binary-indep
rule, because there are no
architecture-independent files created in this package.
There are, however, many architecture-dependent files, so binary-arch
is
used:
binary-arch: checkroot build $(checkdir) rm -rf debian/tmp install -d debian/tmp/DEBIAN $(docdir) install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ prefix=$$(pwd)/debian/tmp/usr install cd debian/tmp && mv usr/info usr/man usr/share cp -a NEWS debian/copyright $(docdir) cp -a debian/changelog $(docdir)/changelog.Debian cp -a ChangeLog $(docdir)/changelog cd $(docdir) && gzip -9 changelog changelog.Debian gzip -r9 debian/tmp/usr/share/man gzip -9 debian/tmp/usr/share/info/* dpkg-shlibdeps debian/tmp/usr/bin/hello dpkg-gencontrol -isp chown -R root:root debian/tmp chmod -R u+w,go=rX debian/tmp dpkg --build debian/tmp ..
First, notice that this rule calls the
checkroot
rule to make sure the package is built as root and calls the
build
rule to compile the source. Then the debian/tmp/DEBIAN
and
debian/tmp/usr/share/doc/hello
files are created, and the postinst
and the prerm>
scripts are installed to debian/tmp/DEBIAN
. Then
make install is run with a prefix that installs to the
debian/tmp/usr
directory. Afterward the documentation files (NEWS, ChangeLog, and the debian
changelog) are gzipped and installed. dpkg-shlibdeps is invoked to find the shared
library dependencies of the hello executable, and it stores the list in the
debian/substvars
file for the ${shlibs:Depends} variable in
control
. Then dpkg-gencontrol is run to create a control file for
the binary package, and it makes the substitutions created by dpkg-shlibdeps. Finally, after
the permissions of the debian/tmp
have been set, dpkg --build is run
to build the binary .deb package and place it in the parent directory.
The postinst
and
prerm
files are examples of maintainer
scripts. They are shell scripts that are executed after
installation and before removal, respectively, of the package. In the case of
the Ubuntu hello package, they
are used to install (and remove) the info file. Go ahead and
copy them into the current debian
directory.
cp ../../ubuntu/hello-2.1.1/debian/postinst . cp ../../ubuntu/hello-2.1.1/debian/prerm .
Now that we have gone through the files in the
debian
directory for
hello in detail, we can build the
source (and binary) packages. First let us move into the
root of the extracted source:
cd ..
Now we build the source package using dpkg-buildpackage:
dpkg-buildpackage -S -rfakeroot
The -S flag tells
dpkg-buildpackage to build a source
package, and the -r flag tells it to use
fakeroot to allow us to have fake
root privileges when making the package.
dpkg-buildpackage will take the
.orig.tar.gz
file and produce a
.diff.gz
(the difference between
the original tarball from the author and the directory we
have created, debian/
and its contents)
and a .dsc
file that has the
description and md5sums for the source package. The
.dsc
and
*_source.changes
(used for uploading the
source package) files are signed using your GPG key. If you do not
have a GPG key, add the -us -uc flags to the invocation of
dpkg-buildpackage. Your package
will build but it cannot be uploaded until it is
signed.
Zusätzlich zu dem Quellpaket, können wir das Binärpaket auch mit pbuilder erstellen:
sudo pbuilder build ../*.dsc
Using pbuilder to build the
binary packages is very important. It ensures that the build
dependencies are correct, because
pbuilder provides only a minimal
environment, so all the build-time dependencies are
determined by the control
file.
Wir können das Quellpaket auf häufige Fehler prüfen, indem wir lintian benutzen:
cd .. lintian -i *.dsc