个人工具

PackagingGuide

来自Ubuntu中文

Calvin.ngei讨论 | 贡献2010年10月25日 (一) 14:14的版本 (準備翻譯)

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航, 搜索

Debian打包入門

Lelanthran K. Manickum

2009年1月13日

1 前言

As part of the efforts behind Ubuntusci[1], software packages not currently in the Ubuntu repository were added to the repository. Doing so required more time and effort than was anticipated, due to the complexity in essentially porting software from other unix-like systems to Ubuntu Linux, or from other Linux distributions to Ubuntu.

It is also safe to assume that any software that has been available for the last 4 to 5 years that is not in at least the Debian repositories, nevermind the Ubuntu repositories, is going to present a few difficulties. If it were as simple as copying the source-code and recompiling them for Ubuntu (and/or Debian), then someone would have done this by now. That it has not been done for any particular software package most probably means that the package does not compile cleanly on Debian and/or Ubuntu.

This document is aimed at those readers who have never before attempted to package software for Debian, as we found that the actual process, in the event that the software compiles and runs error-free, can still be quite hairy. Hopefully, as this project gains momentum more effort would be expended by the community in checking that our packaging efforts are not compromised on quality.

2 工具

There is usually some confusion for the new Ubuntu/Debian developer when using the word source. “Source-code” usually refer to a program or application or package actual source-code. When the word “Sources” is used, it refers to the files used in the creation of a package. For example, the source-code for package Foo would be the text files that are compiled by a GCC to produce binaries while the sources for Foo would be all those files that are needed to produce Foo.deb, including the source-code.

The basic process for packaging is

   * Download the source-code for the package.
   * Un-archive the package source-code into a directory.
   * Create the debianisation directory (./debian).
   * Modify the files in the ./debian directory to reflect the package main-
         o tainers details, the package descriptions, etc. 
   * Compile the package source-code.
   * Create the actual .deb package.
   *
     Upload the created package to our Launchpad PPA[1] . 

At this point, after it has been uploaded to Launchpad and has successfully built on Launchpad, our work is mostly done. Our Launchpad PPA URL can be given to people who need to use our package, and eventually we can ask that our package be moved from our PPA to one of the main Ubuntu repositories.

The minimalist list of tools that will be needed are:

   * A web-browser or similar tool to grab the source-code of the package.
   * An archival tool (such as tar, etc) to un-archive the source-code.
   * dh_make (part of package dh-make) to create the ./debian directory and
         o skeleton files for the .deb creation. 
   * make (Gnu make) a tool that is used by the build process.
   * debchange/dch (part of package devscripts) to manage version numbers
         o of the package. 
   * debuild (part of package devscripts) to run the build process that will
         o both compile the package and generate the .deb file. 
   * fakeroot is needed (part of package fakeroot).
   * dput to upload the signed .deb file. 

I use, and recommend that all packaging efforts be done, on a recent Ubuntu machine, purely because it simplifies the process a great deal.

3 Introducing Alien Packages

An Alien package is one that is targetted for a different system. For example a package targetted for a Red Hat system would be in the RPM package format. Porting these packages to Ubuntu is easier than attempting to package nonpackaged software, mainly because all of the package requirements have already been met, such as run-time dependencies, compile-time dependencies, etc.

The package alien (available in the repositories) can be used to automatically convert packages in selected other package formats to the .deb format. Unfortunately, this is only for binary packages; ideally packaging should only be done from source-code. The sources of any package should be source-code.

4 編譯為類Unix系統定製的源碼包

After downloading the source-code, un-archive all the sources into a directory with a suitable name, for example Foo-1.2.3[2] .

Changing our working directory to the directory we just created with the applications source-code and running dh_make would create the files needed to package the software. Some of the control files will be created as well as the rules file for compiling the software with a default rule.

Most unix packages, having been distributed with a configure script generated by autoconf, should build cleanly without any further work. However, a few applications which have no configure script would need modifications to work. Because the pitfalls inherent in porting and application from a different platform can and do vary[3] , I shall only address the issue of getting a fully working application into Launchpad[4] .

5 從源碼倉庫(Working Sources)創建Ubuntu軟件包

I assume that the reader has downloaded the source-code to a an application and wishes to create a Debian package out of that application. For my example, I’ve written a script-based application[5] that was written as a standalone application, with an installer and an uninstaller that should run on most Linux distributions.

Downloading the Source Code. We can get the version of vob2mpeg that was used for this example from sourceforge. The following command will retrieve the exact version of the application used.

$ svn co https://vob2mpeg.svn.sourceforge.net/svnroot/vob2mpeg/tags/vob2mpeg-0.0.1
A    vob2mpeg-0.0.1/vob2mpeg.profile
A    vob2mpeg-0.0.1/uninstall-vob2mpeg.sh
A    vob2mpeg-0.0.1/vob2mpeg
A    vob2mpeg-0.0.1/LICENCE
A    vob2mpeg-0.0.1/VERSION
A    vob2mpeg-0.0.1/CHANGELOG
A    vob2mpeg-0.0.1/vob2mpeg-install.conf
A    vob2mpeg-0.0.1/CREDITS
A    vob2mpeg-0.0.1/README
A    vob2mpeg-0.0.1/install-vob2mpeg.sh
Checked out revision 7.

No unarchive is necessary in this instance because we retrieved upstream in a form that was not archived. Similarly, no renaming of the directory is needed as the application is already in an appropriately named directory, viz vob2mpeg-0.0.1. What we need to do, however, is create an archive of the original upstream sources so that any changes made to the applications sources can be recorded against the original unchanged upstream sources.

Creating the Debian Control Files. Happily, dh_make can create the archive of the original upstream sources using the --create-orig flag. All the control files for creation of a package are also created by dh_make:

$ cd vob2mpeg-0.0.1/
$ ls -F
CHANGELOG             README                  vob2mpeg-install.conf
CREDITS               uninstall-vob2mpeg.sh* vob2mpeg.profile
install-vob2mpeg.sh* VERSION
LICENCE               vob2mpeg*
$ dh_make --createorig --copyright GPL --email [email protected] --single
Maintainer name : Lelanthran Krishna Manickum
Email-Address   : [email protected]
Date            : Mon, 12 Jan 2009 22:42:04 +0200
Package Name    : vob2mpeg
Version         : 0.0.1
License         : gpl
Type of Package : Single
Hit <enter> to confirm:
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 vob2mpeg Makefiles install into $DESTDIR and not in / .
$ ls -F
CHANGELOG install-vob2mpeg.sh* uninstall-vob2mpeg.sh* vob2mpeg-install.conf
CREDITS    LICENCE                VERSION                vob2mpeg.profile
debian/    README                 vob2mpeg*
$ ls -F debian/
changelog emacsen-install.ex manpage.xml.ex rules*
compat     emacsen-remove.ex    menu.ex        vob2mpeg-default.ex
control    emacsen-startup.ex postinst.ex      vob2mpeg.doc-base.EX
copyright init.d.ex             postrm.ex      watch.ex
cron.d.ex init.d.lsb.ex         preinst.ex
dirs       manpage.1.ex         prerm.ex
docs       manpage.sgml.ex      README.Debian

As we see, a debian directory has been created. This directory contains all of the information needed by the Debian build tools to build the package, including the build instructions to build the application itself. Since this is an interpreted application, no actual compilation of source code is necessary.

Modifying the Control Files. Before we go any further, a few modifications will need to be done on the files in debian. Firstly, the control file must be edited so that each field reflects the correct information. The results of such an edit is below.

$ cat debian/control
Source: vob2mpeg
Section: unknown
Priority: extra
Maintainer: Lelanthran Krishna Manickum <[email protected]>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.7.2
Package: vob2mpeg
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description>
  <insert long description, indented with spaces>
$ vi debian/control
$ cat debian/control
Source: vob2mpeg
Section: graphics
Priority: extra
Maintainer: Lelanthran Krishna Manickum <[email protected]>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.7.2
Package: vob2mpeg
Architecture: any
Depends: ffmpeg, tcl, tk
Homepage: http://vob2mpeg.sourceforge.net/
Description: GUI app to convert VOB files to MPEG files
  A GUI wrapper to convert VOB files to MPEG files using ffmpeg. Allows
  user to change certain attributes of the movies in the conversion,
  such as scale, colour (hue, etc), etc. Can be also totally controlled
  from the command line enabling batch use.
$

Finally, all the example files in the debian directory are not needed for this simple exercise - they are merely examples, so we remove them.

$ rm debian/*.[Ee][Xx]

Modifying the Rules File. Before we go ahead and try to create the Debian package, we still need to modify the rules file. The debian/rules file is a Makefile run by make that will build the application. Since we are not compiling anything, this file will be pared down to only what is needed to create a distribution of the software. This application (vob2mpeg) has an installation (and uninstallation) script that must be run. For example, vob2mpeg is installed on a Linux system by executing the installation script with an optional configuration file that specifies the location of the installation. Since we want all the files to install to ./debian/vob2mpeg, we create a configuration file from the example given in the upstream sources.

$ cp vob2mpeg-install.conf debian/
$ cat debian/vob2mpeg-install.conf
#
# Installation settings for vob2mpeg installation script
# Store variables in this file so that porting to different
# packaging systems becomes trivial and not hellish
#
# Variables in this file are never over-ridden, uncomment
# the lines below and replace with your own settings
#
export DEST_ETC=/tmp/test/etc
export DEST_BIN=/tmp/test/usr/bin
export DEST_DOC=/tmp/test/usr/share/doc/vob2mpeg
# The files to actually install, please do not change this
export ETC_FILES="vob2mpeg.profile $CONF_FILE"
export DOC_FILES="README CREDITS LICENCE VERSION CHANGELOG"
export BIN_FILES="vob2mpeg install-vob2mpeg.sh uninstall-vob2mpeg.sh"
#
$ vi debian/vob2mpeg-install.conf
$ cat debian/vob2mpeg-install.conf
#
# Installation settings for vob2mpeg installation script
# Store variables in this file so that porting to different
# packaging systems becomes trivial and not hellish
#
# Variables in this file are never over-ridden, uncomment
# the lines below and replace with your own settings
#
export DEST_ETC=debian/vob2mpeg/etc
export DEST_BIN=debian/vob2mpeg/usr/bin
export DEST_DOC=debian/vob2mpeg/usr/share/doc/vob2mpeg
# The files to actually install, please do not change this
export ETC_FILES="vob2mpeg.profile $CONF_FILE"
export DOC_FILES="README CREDITS LICENCE VERSION CHANGELOG"
export BIN_FILES="vob2mpeg install-vob2mpeg.sh uninstall-vob2mpeg.sh"
#
$

So, we ensure that when we run the vob2mpeg installation script, it would install itself to ./debian/vob2mpeg. We can then create the .deb file from the files in that directory. Now we modify the rules file to tell it how to build the package files (the files that will be installed). Because we will only be modifying the build, install and the clean targets, I will <...snip...> out the rest of the file.

$ cat debian/rules
#!/usr/bin/make -f
<...snipped...>
build-stamp: configure-stamp
        dh_testdir
         # Add here commands to compile the package.
         $(MAKE)
         #docbook-to-man debian/vob2mpeg.sgml > vob2mpeg.1
         touch $@
clean:
         dh_testdir
         dh_testroot
         rm -f build-stamp configure-stamp
         # Add here commands to clean up after the build process.
         -$(MAKE) clean
         dh_clean
install: build
        dh_testdir
        dh_testroot
        dh_clean -k
        dh_installdirs
        # Add here commands to install the package into debian/vob2mpeg.
        $(MAKE) DESTDIR=$(CURDIR)/debian/vob2mpeg install
<...snipped...>
$ vi debian/rules
$ cat debian/rules
#!/usr/bin/make -f
<...snipped...>
build-stamp: configure-stamp
        dh_testdir
         # Add here commands to compile the package.
         #docbook-to-man debian/vob2mpeg.sgml > vob2mpeg.1
         touch $@
clean:
         dh_testdir
         dh_testroot
         rm -f build-stamp configure-stamp
         # Add here commands to clean up after the build process.
         rm -rf ./debian/vob2mpeg
         dh_clean
install: build
        dh_testdir
        dh_testroot
        dh_clean -k
        dh_installdirs
        # Add here commands to install the package into debian/vob2mpeg.
        ./install-vob2mpeg.sh ./debian/vob2mpeg-install.conf
<...snipped...>
$

The only lines that have been changed are those that execute the compilation, the installation of the files and the removal of all the files, so the targets build, install and clean have been modified so that compile does nothing (there is nothing to compile), the target install merely calls the installation program to install the files to the debian/vob2mpeg directory and the clean target only removes that same directory.

Note that we have neglected to provide the preinst and postinst scripts in the debian/ directory. These scripts, if present, are respectively run prior to installation of the package and after the removal of the package. This particular application has no need to run any commands before installation nor any commands after removal.

Package Creation. Now that we are done with all the changes we wish to make, we can issue the commands required to create the .deb file. Before we do so, however, we need to ensure that the correct Debian package version number is reflected in the newly created package. This should not be confused with the applications version number, which is the version number of the application. The package version number is the version of our package. For example, it is possible that for application Foo we decide to package version 1 of the applica- tion. In other words, the directory we use is Foo-1.0.0. After packaging Foo, we assign that package the version number 0.0.1.

Now let’s assume that there was an error in the packaging, for example, perhaps we compiled Foo using a flag that caused it to break on lpia architectures. A user submits a report and we quickly fix the problem. This results in the package having the new version of 0.0.2 while the application itself is still Foo-1.0.0.

Updating the Version Number. To automatically manage the version numbers of the package, we use a tool called dch. A plain invocation of dch without any command-line arguments results in an increment of the minor ver- sion number, while invoking it as dch -i results in the package recieving an increment to the major version number.

Upon running dch for the first time, we are presented with an editor[6] that should display something similar to the following:

vob2mpeg (0.0.1-1) unstable; urgency=low
  * Initial release (Closes: #nnnn)   <nnnn is the bug number of your ITP>
  *
 -- Lelanthran Krishna Manickum <lmanickum@esprit>   Mon, 12 Jan 2009 23:39:19 +0200

We edit the above file so that unstable is replaced with the actual Debian distribution name (in this example I use Intrepid, as that is what was used in the production of this document and the package). Each comment should also follow the given convention, starting with an asterisk and indented to the previous line. The changed file looks like this:

vob2mpeg (0.0.1-1) intrepid; urgency=low
  *   Initial release
  *   Edited rules and removed build instructions
  *   Edited rules and replaced command for installation
  *   Edited rules and replaced command for target ’clean’
 -- Lelanthran Krishna Manickum <lmanickum@esprit>   Mon, 12 Jan 2009 23:39:19 +0200

Now we can go ahead and create the actual .deb archive by running the debian/rules script, like this:

$ fakeroot debian/rules binary-arch
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/vob2mpeg.
./install-vob2mpeg.sh ./debian/vob2mpeg-install.conf
Found installation configuration in ./debian/vob2mpeg-install.conf
-----------./debian/vob2mpeg-install.conf--------------
DEST_ETC is already set to debian/vob2mpeg/etc
DEST_BIN is already set to debian/vob2mpeg/usr/bin
DEST_DOC is already set to debian/vob2mpeg/usr/share/doc/vob2mpeg
ETC_FILES is already set to vob2mpeg.profile ./debian/vob2mpeg-install.conf
DOC_FILES is already set to README CREDITS LICENCE VERSION CHANGELOG
BIN_FILES is already set to vob2mpeg install-vob2mpeg.sh uninstall-vob2mpeg.sh
install: creating directory ‘debian/vob2mpeg/etc’
install: creating directory ‘debian/vob2mpeg/usr/share’
install: creating directory ‘debian/vob2mpeg/usr/share/doc’
install: creating directory ‘debian/vob2mpeg/usr/share/doc/vob2mpeg’
‘vob2mpeg.profile’ -> ‘debian/vob2mpeg/etc/vob2mpeg.profile’
‘./debian/vob2mpeg-install.conf’ -> ‘debian/vob2mpeg/etc/vob2mpeg-install.conf’
‘README’ -> ‘debian/vob2mpeg/usr/share/doc/vob2mpeg/README’
‘CREDITS’ -> ‘debian/vob2mpeg/usr/share/doc/vob2mpeg/CREDITS’
‘LICENCE’ -> ‘debian/vob2mpeg/usr/share/doc/vob2mpeg/LICENCE’
‘VERSION’ -> ‘debian/vob2mpeg/usr/share/doc/vob2mpeg/VERSION’
‘CHANGELOG’ -> ‘debian/vob2mpeg/usr/share/doc/vob2mpeg/CHANGELOG’
‘vob2mpeg’ -> ‘debian/vob2mpeg/usr/bin/vob2mpeg’
‘install-vob2mpeg.sh’ -> ‘debian/vob2mpeg/usr/bin/install-vob2mpeg.sh’
‘uninstall-vob2mpeg.sh’ -> ‘debian/vob2mpeg/usr/bin/uninstall-vob2mpeg.sh’
dh_testdir
dh_testroot
dh_installchangelogs CHANGELOG
dh_installdocs
dh_installexamples
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dpkg-gencontrol: warning: unknown substitution variable ${shlibs:Depends}
dpkg-gencontrol: warning: unknown substitution variable ${misc:Depends}
dh_md5sums
dh_builddeb
dpkg-deb: building package ‘vob2mpeg’ in ‘../vob2mpeg_0.0.1-1_i386.deb’.
$

This creates the debian/vob2mpeg directory tree, and uses that tree, along with the control files, to create the ../vob2mpeg_0.0.1-1_i386.deb file. At this point, we can stop if we only want to create packages for our own use. However, if we need to distribute our packages (such as through Launchpad), then we need to ensure that our package is signed by our Launchpad key.

6 上傳並發佈軟件包

Launchpad provides a very convenient way to redistribute our packages. We simply upload the upstream sources, upload the changes we made to the upstream sources and let Launchpad then build the packages for us. This ensures that, not only do we build our packages on our local machine, but we also find out if the package builds on the various Launchpad virtual machines.

The very first thing to do, if we haven’t already done so, is to create a Launchpad account for us to use. This account will give us a PPA, or Personal Package Archive. All the packages we upload will go into our PPA, and the URL for our PPA can be added to any sources.list file so that our package can be installed via the normal apt-get or synaptic methods by the user.

All the steps in creating an account on Launchpad is beyond the scope of this report, but full instructions and comprehensive help is available on Launchpad itself - https://launchpad.net/. Part of the creation of the Launchpad account requires the user to generate a cryptography key and use this key to digitally sign the code of conduct. This very same will will be used to generate a digitally signed package.

Signing. Once we have tested that our rules file works, we are ready to send the upstream sources and our changes to Launchpad. The program debuild generates a set of files suitable for Launchpad. We specify the key to use when digitally signing the package.

$ debuild -S -kFB43CE54
 dpkg-buildpackage -rfakeroot -d -us -uc -S
dpkg-buildpackage: set CFLAGS to default value: -g -O2
dpkg-buildpackage: set CPPFLAGS to default value:
dpkg-buildpackage: set LDFLAGS to default value: -Wl,-Bsymbolic-functions
dpkg-buildpackage: set FFLAGS to default value: -g -O2
dpkg-buildpackage: set CXXFLAGS to default value: -g -O2
dpkg-buildpackage: source package vob2mpeg
dpkg-buildpackage: source version 0.0.1-1
dpkg-buildpackage: source changed by Lelanthran Krishna Manickum <lmanickum@esprit>
 fakeroot debian/rules clean
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
# Add here commands to clean up after the build process.
rm -rf ./debian/vob2mpeg
dh_clean
 dpkg-source -b vob2mpeg-0.0.1
dpkg-source: info: using source format ‘1.0’
dpkg-source: info: building vob2mpeg using existing vob2mpeg_0.0.1.orig.tar.gz
dpkg-source: info: building vob2mpeg in vob2mpeg_0.0.1-1.diff.gz
dpkg-source: info: building vob2mpeg in vob2mpeg_0.0.1-1.dsc
 dpkg-genchanges -S >../vob2mpeg_0.0.1-1_source.changes
dpkg-genchanges: including full source code in upload
dpkg-buildpackage: source only upload (original source is included)
Now running lintian...
E: vob2mpeg_0.0.1-1_source.changes: bad-distribution-in-changes-file intrepid
W: vob2mpeg source: out-of-date-standards-version 3.7.2 (current is 3.8.0)
W: vob2mpeg source: changelog-should-mention-nmu
W: vob2mpeg source: source-nmu-has-incorrect-version-number 0.0.1-1
Finished running lintian.
Now signing changes and any dsc files...
 signfile vob2mpeg_0.0.1-1.dsc FB43CE54
You need a passphrase to unlock the secret key for
user: "Lelanthran Krishna Manickum (Final) <[email protected]>"
1024-bit DSA key, ID FB43CE54, created 2008-10-15


 signfile vob2mpeg_0.0.1-1_source.changes FB43CE54
You need a passphrase to unlock the secret key for
user: "Lelanthran Krishna Manickum (Final) <[email protected]>"
1024-bit DSA key, ID FB43CE54, created 2008-10-15


Successfully signed dsc and changes files
$ ls -F ..
vob2mpeg-0.0.1/            vob2mpeg_0.0.1-1_source.build
vob2mpeg_0.0.1-1.diff.gz   vob2mpeg_0.0.1-1_source.changes
vob2mpeg_0.0.1-1.dsc       vob2mpeg_0.0.1.orig.tar.gz
vob2mpeg_0.0.1-1_i386.deb
$

Uploading. Now that we have a set of files that are signed with our key, all thats left is to upload those files to Launchpad. A program called dput is used. In order to use it, we need a ~/.dput.cf that specifies the Launchpad account to beused. My ~/.dput.cf file looks like this:

$ cat ~/.dput.cf
[my-ppa]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~lmanickum/ubuntu/
login = anonymous
allow_unsigned_uploads = 0

When using dput to upload files to my lmanickum account on Launchpad I will tell dput to use the profile my-ppa, like this:

$ cd ..
$ dput my-ppa vob2mpeg_0.0.1-1_source.changes
Checking Signature on .changes
gpg: Signature made Tue 13 Jan 2009 08:13:33 SAST using DSA key ID FB43CE54
gpg: Good signature from "Lelanthran Krishna Manickum (Final) <[email protected]>"
Good signature on /home/lelanthran/pack/vob2mpeg_0.0.1-1_source.changes.
Checking Signature on .dsc
gpg: Signature made Tue 13 Jan 2009 08:13:23 SAST using DSA key ID FB43CE54
gpg: Good signature from "Lelanthran Krishna Manickum (Final) <[email protected]>"
Good signature on /home/lelanthran/pack/vob2mpeg_0.0.1-1.dsc.
Uploading to my-ppa (via ftp to ppa.launchpad.net):
  vob2mpeg_0.0.1-1.dsc: done.
  vob2mpeg_0.0.1.orig.tar.gz: done.
  vob2mpeg_0.0.1-1.diff.gz: done.
  vob2mpeg_0.0.1-1_source.changes: done.
Successfully uploaded packages.
Not running dinstall.
$

PPA. If a problem exists, then Launchpad will notify us via email. Once Launchpad has unarchived our upstream sources, applied our changes, run the build and install targets[7] and created the .deb file, then we should see the package listed in ourPPA, as shown in Figure 1. If there are problems, then they will also be listed there, and clicking on the relevant text will take you to the build log, which will help you identify the problem.