章 6. 構建套件

內容目錄

6.1. 完整的(重)構建
6.2. 自動編譯系統
6.3. debuild 命令
6.4. pbuilder 套件
6.5. git-buildpackage 和相似命令
6.6. 快速重構建

現在我們已經爲構建套件做好了準備。

6.1. 完整的(重)構建

In order to perform a complete (re)build of a package properly, you need to make sure you have installed

然後在原始碼目錄中執行以下命令:

$ dpkg-buildpackage

這樣會自動完成所有從原始碼套件構建二進位套件的工作,包括:

  • 清理原始碼樹(debian/rules clean)

  • 構建原始碼套件(dpkg-source -b)

  • 構建程式(debian/rules build)

  • 構建二進位套件(fakeroot debian/rules binary)

  • 使用 gpg 簽署 .dsc 檔案

  • 使用 dpkg-genchangesgpg 創建並簽署上傳用的 .changes 檔案

The only input that will be required of you is your GPG secret pass phrase, twice. [64] If you are building Debian packages only for your own local use, you can skip promptings for the GPG signatures on the .dsc file and the .changes file like this:

$ dpkg-buildpackage -us -uc

For a non-native Debian package, e.g., gentoo, you will see the following files in the parent directory (~/gentoo) after building packages:

  • gentoo_0.9.12.orig.tar.gz

    This is the original upstream source code tarball, merely renamed to the above so that it adheres to the Debian standard. Note that this was created initially by the dh_make -f ../gentoo-0.9.12.tar.gz.

  • gentoo_0.9.12-1.dsc

    這是一個從 control 檔案生成的原始碼概要,可用於 dpkg-source(1) 程式。這個檔案是使用 GPG 簽署過的,以便別人可以確信它確實是你所提供的。

  • gentoo_0.9.12-1.debian.tar.gz

    This compressed tarball contains your debian directory contents. Each and every addition you made to the original source code is stored as a quilt patch in debian/patches.

    如果其他人想要重新構建你的套件,他們可以使用以上三個檔案很容易地完成。只需複製三個檔案,再運行 dpkg-source -x gentoo_0.9.12-1.dsc[65]

  • gentoo_0.9.12-1_i386.deb

    這是你的二進位套件,可以使用 dpkg 程式安裝或反安裝它,就像其他套件一樣。

  • gentoo_0.9.12-1_i386.changes

    This file describes all the changes made in the current package revision; it is used by the Debian FTP archive maintenance programs to install the binary and source packages. It is partly generated from the changelog file and the .dsc file. This file is GPG signed, so that people can be sure that it's really yours.

    As you keep working on the package, its behavior will change and new features will be added. People downloading your package can look at this file and quickly see what has changed. Debian archive maintenance programs will also post the contents of this file to the debian-devel-changes@lists.debian.org mailing list.

The long strings of numbers in the .dsc and .changes files are SHA1/SHA256 checksums for the files mentioned. Anyone downloading your files can test them with sha1sum(1) or sha256sum(1) and if the numbers don't match, they'll know the file is corrupt or has been tampered with.

For a native Debian package, e.g., mypackage, you will see the following files in the parent directory after building packages:

  • mypackage_1.0.tar.gz

    This is the source code tarball created from the mypackage-1.0 directory by the dpkg-source command. (Its suffix is not orig.tar.gz.)

  • mypackage_1.0.dsc

    This is a summary of the contents of the source code as in the non-native Debian package. (There is no Debian revision.)

  • mypackage_1.0_i386.deb

    This is your completed binary package as in the non-native Debian package. (There is no Debian revision.)

  • mypackage_1.0_i386.changes

    This file describes all the changes made in the current package version as in the non-native Debian package. (There is no Debian revision.)

6.2. 自動編譯系統

Debian supports many ports with the autobuilder network running buildd daemons on computers of many different architectures. Although you do not need to do this yourself, you should be aware of what will happen to your packages. Let's look into roughly how they rebuild your packages for multiple architectures. [66]

For Architecture: any packages, the autobuilder system performs a rebuild. It ensures the installation of

然後在原始碼目錄中執行以下命令:

$ dpkg-buildpackage -B

這樣會自動完成從原始碼套件構建平臺依賴二進位套件的工作,包括:

  • 清理原始碼樹(debian/rules clean)

  • 構建程式(debian/rules build)

  • 構建平臺依賴二進位套件(fakeroot debian/rules binary-arch)

  • 使用 gpg 簽署 .dsc 檔案

  • 使用 dpkg-genchangesgpg 創建並簽署上傳用的 .changes 檔案

這就是你看到你的套件在其他平臺上可用的原因。

Although packages listed in the Build-Depends-Indep field are required to be installed for our normal packaging work (see 節 6.1, “完整的(重)構建”), they are not required to be installed for the autobuilder system since it builds only architecture dependent binary packages. [67] This distinction between normal packaging and autobuilding procedures is what dictates whether you should record such required packages in the Build-Depends or Build-Depends-Indep fields of the debian/control file (see 節 4.1, “control).

6.3. debuild 命令

You can automate the dpkg-buildpackage command's package build process further with the debuild command. See debuild(1).

Customization of the debuild command can be done through /etc/devscripts.conf or ~/.devscripts. I would suggest at least the following items:

DEBSIGN_KEYID=Your_GPG_keyID
DEBUILD_LINTIAN_OPTS="-i -I --show-overrides"

With these, packages are signed by your specified GPG key ID (good for sponsoring packages) and checked in detail by the lintian command.

Cleaning the source and rebuilding the package from your user account is as simple as:

$ debuild

Here, if you are building Debian packages only for your own local use, you can skip promptings for the GPG signatures on the .dsc file and the .changes file like this:

$ debuild -us -uc

You can clean the source tree as simply as:

$ debuild clean

6.4. pbuilder 套件

For a clean room (chroot) build environment to verify the build dependencies, the pbuilder package is very useful. [68] This ensures a clean build from the source under the sid auto-builder for different architectures and avoids a severity serious FTBFS (Fails To Build From Source) bug which is always in the RC (release critical) category. [69]

Let's customize the pbuilder package as follows:

  • setting the /var/cache/pbuilder/result directory writable by your user account.

  • creating a directory, e.g. /var/cache/pbuilder/hooks, writable by the user, to place hook scripts in.

  • configuring ~/.pbuilderrc or /etc/pbuilderrc to include the following.

    AUTO_DEBSIGN=${AUTO_DEBSIGN:-yes}
    HOOKDIR=/var/cache/pbuilder/hooks
    

這使你可以使用 ~/.gnupg/ 目錄中的 GPG 私鑰簽署生成的套件。

First let's initialize the local pbuilder chroot system as follows.

$ sudo pbuilder create

If you already have a completed source package, issue the following commands in the directory where the foo.orig.tar.gz, foo.debian.tar.gz, and foo.dsc files exist to update the local pbuilder chroot system and to build binary packages in it.

$ sudo pbuilder --update
$ sudo pbuilder --build foo_version.dsc

The newly built packages without the GPG signatures will be located in /var/cache/pbuilder/result/ with non-root ownership.

The GPG signatures on the .dsc file and the .changes file can be generated as:

$ cd /var/cache/pbuilder/result/
$ debsign foo_version.dsc
$ debsign foo_version_arch.changes

If you have an updated source tree but have not generated the matching source package, issue the following commands in the source directory where the debian directory exists, instead.

$ sudo pbuilder --update
$ pdebuild

Here, if you are building Debian packages only for your local use, you can skip promptings for the GPG signatures on the .dsc file and the .changes file as:

$ AUTO_DEBSIGN=no pdebuild

你可以使用 pbuilder --login --save-after-login 命令登錄到這個 chroot 環境中並按照需要對其進行設定。通過 ^D (Control-D)離開這個 shell 時環境會被保存。

最新版的 lintian 命令可以通過設置鉤子腳本 /var/cache/pbuilder/hooks/B90lintianchroot 環境中運行。腳本內容如下:[70]

#!/bin/sh
set -e
install_packages() {
        apt-get -y --force-yes install "$@"
        }
install_packages lintian
echo "+++ lintian output +++"
su -c "lintian -i -I --show-overrides /tmp/buildd/*.changes" - pbuilder
# use this version if you don't want lintian to fail the build
#su -c "lintian -i -I --show-overrides /tmp/buildd/*.changes; :" - pbuilder
echo "+++ end of lintian output +++"

You need to have access to the latest sid environment to build packages properly for sid. In practice, sid may be experiencing issues which makes it undesirable for you to migrate your whole system. The pbuilder package can help you to cope with this kind of situation.

You may need to update your stable packages after their release for stable-proposed-updates, stable/updates, etc. [71] For such occasions, the fact you may be running a sid system is not a good enough excuse for failing to update them promptly. The pbuilder package can help you to access environments of almost any Debian derivative distribution of the same architecture.

See http://www.netfort.gr.jp/~dancer/software/pbuilder.html, pdebuild(1), pbuilderrc(5), and pbuilder(8).

6.5. git-buildpackage 和相似命令

If your upstream uses a source code management system (VCS) [72] to maintain their code, you should consider using it as well. This makes merging and cherry-picking upstream patches much easier. There are several specialized wrapper script packages for Debian package building for each VCS.

  • git-buildpackage: a suite to help with Debian packages in Git repositories.

  • svn-buildpackage:幫助維護 Subversion 倉庫中套件的程式。

  • cvs-buildpackage: a set of Debian package scripts for CVS source trees.

Use of git-buildpackage is becoming quite popular for Debian Developers to manage Debian packages with the Git server on alioth.debian.org. [73] This package offers many commands to automate packaging activities.

  • git-import-dsc(1): import previous Debian package to a Git repository.

  • git-import-orig(1): import new upstream tar to a Git repository.

  • git-dch(1): generate the Debian changelog from Git commit messages.

  • git-buildpackage(1): build Debian packages from a Git repository.

  • git-pbuilder(1): build Debian packages from a Git repository using pbuilder/cowbuilder.

These commands use 3 branches to track packaging activity.

  • main for Debian package source tree.

  • upstream for upstream source tree.

  • pristine-tar for upstream tarball generated by the --pristine-tar option.[74]

You can configure git-buildpackage with ~/.gbp.conf. See gbp.conf(5). [75]

6.6. 快速重構建

With a large package, you may not want to rebuild from scratch every time while you're tuning details in debian/rules. For testing purposes, you can make a .deb file without rebuilding the upstream sources like this[76]:

$ fakeroot debian/rules binary

Or simply do the following to see if it builds or not:

$ fakeroot debian/rules build

一旦完成了調試,記住要按照前面所將的正常過程重構建你的套件。你可能無法正常上傳用此種方法構建的 .deb 檔案。



[64] This GPG key must be signed by a Debian developer to get connected to the web of trust and must be registered to the Debian keyring. This enables your uploaded packages to be accepted to the Debian archives. See Creating a new GPG key and Debian Wiki on Keysigning.

[65] You can avoid applying quilt patches in the 3.0 (quilt) source format at the end of the extraction with the --skip-patches option. Alternatively, you can run dquilt pop -a after normal operation.

[66] The actual autobuilder system involves much more complicated schemes than the one documented here. Such details are beyond the scope of this document.

[67] Unlike under the pbuilder package, the chroot environment under the sbuild package used by the autobuilder system does not enforce the use of a minimal system and may have many leftover packages installed.

[68] Since the pbuilder package is still evolving, you should check the actual configuration situation by consulting the latest official documentation.

[69] See http://buildd.debian.org/ for more on Debian package auto-building.

[70] This assumes HOOKDIR=/var/cache/pbuilder/hooks. You can find many examples of hook scripts in the /usr/share/doc/pbuilder/examples directory.

[71] 升級你的 stable 套件有規定限制。

[72] See Version control systems for more.

[73] Debian wiki Alioth documents how to use the alioth.debian.org service.

[74] The --pristine-tar option invokes the pristine-tar command which can regenerate an exact copy of a pristine upstream tarball using only a small binary delta file and the contents of the tarball, which are typically kept in an upstream branch in the VCS.

[75] Here are some web resources available for advanced audiences.

[76] 常規情形下被設定好的環境變量在此時不會被自動設置。永遠不要將使用這個 快速 方法構建的套件上傳到任何地方。