Debian构建软件包

1 完整的(重)构建

为保证完整的软件包(重)构建能顺利进行,你必须保证系统中已经安装:

  • build-essential 软件包;

  • 列于 Build-Depends 域的软件包(参看 control 文件, 第 4.1 节);

  • 列于 Build-Depends-indep 域的软件包(参看 control 文件, 第 4.1 节)。

然后在源代码目录中执行以下命令:

     $ dpkg-buildpackage

这样会自动完成所有从源代码包构建二进制包的工作,包括:

  • 清理源代码树(debian/rules clean)

  • 构建源代码包(dpkg-source -b)

  • 构建程序(debian/rules build)

  • 构建二进制包(fakeroot debian/rules binary)

  • 使用 gpg 签署 .dsc 文件

  • 使用 dpkg-genchanges 和 gpg 创建并签署上传用的 .changes 文件

这个过程中你需要做的就是输入两次你的 GPG 私钥密码。

之后查看上级目录(~/gentoo):

  • gentoo_0.9.12.orig.tar.gz

    这是原始的源代码 tarball,由 dh_make -f ../gentoo-0.9.12.tar.gz 命令重命名以符合 Debian 的标准。

  • gentoo_0.9.12-1.dsc

    这是一个从 control 文件生成的源代码概要,可用于 dpkg-source(1) 程序。这个文件是使用 GPG 签署过的,以便别人可以确信它确实是你所提供的。

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

    这个压缩的 Tar 归档包含你的 debian 目录。其他对于源代码的修改都由 quilt 补丁存储于 debian/patches 中。

    如果其他人想要重新构建你的软件包,他们可以使用以上三个文件很容易地完成。只需复制三个文件,再运行 dpkg-source -x gentoo_0.9.12-1.dsc。 [41]

  • gentoo_0.9.12-1_i386.deb

    这是你的二进制包,可以使用 dpkg 程序安装或卸载它,就像其他软件包一样。

  • gentoo_0.9.12-1_i386.changes

    这个文件描述了当前版本的软件包中的全部变更,它被 Debian FTP 仓库维护程序用于安装二进制和源代码包。它的是部分从 changelog 和 .dsc 文件生成的,并使用 GPG 签名以便别人可以确信它确实是你提供的。

    随着你不断完善这个软件包,程序的行为会发生变化,也会有更多新特性添加进来。下载你软件包的人可以查看这个文件来快速找到有那些变化,Debian 仓库维护程序还会把它的内容发表至 debian-devel-announce@lists.debian.org 邮件列表。

.dsc 和 .changes 文件中很长的数字串是其中提及文件的 MD5/SHA1/SHA256 校验和。下载你软件包的人可以使用 md5sum(1)、sha1sum(1) 或 sha256sum(1) 来进行核对。如果校验和不符,则说明文件已被损坏或偷换。

2 自动编译系统

Debian 通过在各种不同构架的计算机上运行 buildd 守护进程组成的 autobuilder network 来支持多种 ports。尽管这些工作不需要全由你完成,我们现在仍然要大致看看在各种构架上你的软件包是如果被构建的。[42]

对于 Architecture: any 的软件包,自动编译系统重构建它们,它确保系统中已经安装:

  • build-essential 软件包;

  • 列于 Build-Depends 域的软件包(参看 control 文件, 第 4.1 节)。

然后在源代码目录中执行以下命令:

     $ dpkg-buildpackage -B

这样会自动完成从源代码包构建平台依赖二进制包的工作,包括:

  • 清理源代码树(debian/rules clean)

  • 构建程序(debian/rules build)

  • 构建平台依赖二进制包(fakeroot debian/rules binary-arch)

  • 使用 gpg 签署 .dsc 文件

  • 使用 dpkg-genchanges 和 gpg 创建并签署上传用的 .changes 文件

这就是你看到你的软件包在其他平台上可用的原因。

尽管通常的打包工作中 Build-Depends-indep 域中列出的软件包都需要安装(参看 完整的(重)构建, 第 6.1 节),但是在编译平台依赖二进制包时它们无需在自动编译系统上安装。[43]通常打包和自动编译系统的这种不同为你指出如何考虑必须的软件包应如何放在 debian/control 文件的 Build-Depends 或 Build-Depends-indep 域中(参看 control 文件, 第 4.1 节)。

3 在上传时包含 orig.tar.gz 文件

第一次向仓库上传软件包时要包含 orig.tar.gz 源代码归档。如果 changelog 中的最后一个条目是这个上游版本的第一次上传,那么应为 dpkg-buildpackage 命令传递 -sa 选项。相反,-sd 选项会强制将原始的 orig.tar.gz 源代码归档排除在外。

4 debuild 命令

你可以使用 debuild 命令来进一步自动化 dpkg-buildpackage 的构建过程。参看 debuild(1)

对 debuild 命令的自定义可以通过 /etc/devscripts.conf 或 ~/.devscripts 实现。我建议至少添加以下几项:

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

这样软件包会使用指定的 ID 的 GPG 私钥签署(对于 sponsor 软件包有好处),并使用 lintian 命令对软件包做最大程度的检查。

在普通用户帐号中可以使用以下这样简单的命令清理源代码并重构建软件包:

     $ debuild

请注意用于包含 orig.tar.gz 源代码归档的 dpkg-buildpackage 参数 -sa 可以这样传递:

     $ debuild -sa

还可以简单地清理源代码树:

     $ debuild clean

5 pbuilder 软件包

对于使用净室(chroot)编译环境来验证编译依赖而言,pbuilder 软件包是非常有用的。[44]它确保了软件包在不同构架上的 sid 发行版环境中的自动编译器中能成功编译,避免了总是被归类于 RC (Release Critical,影响发布)的严重 FTBFS (Fails To Build From Source,从源代码编译失败) Bug。参看 http://buildd.debian.org/ 以更多了解 Debian 软件包自动编译系统。

我们通过以下操作来定制 pbuilder 软件包。

  • 设置 /var/cache/pbuilder/result 对用户可写。

  • 创建一个对用户可写的目录保存钩子脚本,例如 /var/cache/pbuilder/hooks

  • 在 ~/.pbuilderrc 或 /etc/pbuilderrc 中添加以下内容:

         AUTO_DEBSIGN=yes
         HOOKDIR="/var/cache/pbuilder/hooks"
    

这使你可以使用 ~/.gnupg/ 目录中的 GPG 私钥签署生成的软件包。

使用以下命令初始化 pbuilder chroot 系统:

     $ sudo pbuilder create

如果你已经创建了源代码包,在包含 foo.orig.tar.gz、foo.debian.tar.gz 和 foo.dsc 文件的目录中执行下面的命令来更新 pbuilder chroot 系统以便执行构建。

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

请注意用于包含 orig.tar.gz 源代码归档的 dpkg-buildpackage 参数 -sa 可以这样传递:

     $ sudo pbuilder --build --debbuildopts "-sa" foo.dsc

新构建的软件包将被放置于 /var/cache/pbuilder/result/ 且属主不是 root。

如果你已经更新了源代码树但没有生成对应的源代码包,在存放 debian 目录的目录里执行:

     $ sudo pbuilder --update
     $ pdebuild

请注意用于包含 orig.tar.gz 源代码归档的 dpkg-buildpackage 参数 -sa 可以这样传递:

     $ pdebuild --debbuildopts "-sa"

你可以使用 pbuilder --login --save-after-login 命令登录到这个 chroot 环境中并按照需要对其进行配置。通过 ^D (Control-D)离开这个 shell 时环境会被保存。

最新版的 lintian 命令可以通过设置钩子脚本 /var/cache/pbuilder/hooks/B90lintian 在 chroot 环境中运行。脚本内容如下:[45]

     #!/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 +++"

为 sid 编译软件包需要使用 sid 环境。在现实中 sid 存在很多问题以至于你不愿意将整个系统都迁移到其上。pbuilder 可以在这种情况下很好地解决问题。

你可能需要通过 stable-proposed-updates、stable/updates 等升级你的 stable 软件包。[46]对于这类情况,“我正在运行 sid 系统” 并不是你不为它们进行升级的充分理由。pbuilder 软件包可以帮助你使用到相同 CPU 构架下几乎所有 Debian 和 Debian 衍生版系统。

参看 http://www.netfort.gr.jp/~dancer/software/pbuilder.html、pdebuild(1)、pbuilderrc(5) 和 pbuilder(8)

6 git-buildpackage 和相似命令

如果你的上游对源代码使用版本控制系统(VCS),你也应该考虑使用它们。这会使得合并和提取上游补丁更加简单。在 Debian 有多个为不同 VCS 设计的脚本软件包来协助 Debian 软件包构建。

  • git-buildpackage:帮助维护 Git 仓库中软件包的套件。

  • topgit:一个 Git 补丁队列管理器。

  • svn-buildpackage:帮助维护 Subversion 仓库中软件包的程序。

  • cvs-buildpackage:为 CVS 源代码树设计的 Debian 软件包脚本集。

这些软件包为需要 自动化 编译软件包的资深打包人员提供了相比于手工使用 quilt 命令更加整洁的工作环境,本文档里不会对此进行更多叙述。[47]

7 快速重构建

对于很大的软件包,在调试 debian/rules 的过程中你可能不想对整个软件包进行重构建。仅用于测试目的,你可以不重新构建源代码包而使用以下的方法创建 .deb 文件[48]:

     $ fakeroot debian/rules binary

或者可以仅查看它是否能通过编译:

     $ fakeroot debian/rules build

一旦完成了调试,记住要按照前面所将的正常过程重构建你的软件包。你可能无法正常上传用此种方法构建的 .deb 文件。

作者: cywcdwxjf   发布时间: 2010-10-11