Chapter 7. 提示

这里有一些关于 Debian 打包的值得注意的提示。

7.1. debdiff

您可以使用 debdiff 命令来对比两个 Debian 软件包组成的差别。

  1. $ debdiff old-package.dsc new-package.dsc

您也可以使用 debdiff 命令来对比两组二进制 Debian 软件包中的文件列表。

  1. $ debdiff old-package.changes new-package.changes

当检查源代码包中哪些文件被修改时,这个命令非常有用。它还可以用来检测二进制包中是否有文件在更新过程中发生变动,比如被意外替换或删除。

7.2. dget

您可以使用 dget 命令来下载 Debian 源包的文件集。

  1. $ dget https://www.example.org/path/to/package_version-rev.dsc

7.3. debc

您应该使用 debc 命令安装生成的软件包以在本地测试它。

  1. $ debc package_version-rev_arch.changes

7.4. piuparts

您应该使用 piuparts 命令安装生成的软件包以自动进行测试。

  1. $ sudo piuparts package_version-rev_arch.changes
[Note]Note

这是一个非常慢的过程,因为它需要访问远程 APT 软件包仓库。

7.5. debsign

完成软件包的测试后,您可以使用 debsign 命令对其进行签名。

  1. $ debsign package_version-rev_arch.changes

7.6. dput

使用 debsign 命令对包进行签名后,您可以使用 dput 命令上传 Debian 源和二进制包的文件集。

  1. $ dput package_version-rev_arch.changes

7.7. bts

上传软件包后,您将收到错误报告。 如《Debian 开发者参考》5.8. 处理缺陷 中所述,正确地管理这些错误是软件包维护者的一项重要职责。

bts 命令是一个用以处理 Debian 缺陷追踪系统 上的错误的便捷工具。

  1. $ bts severity 123123 wishlist , tags -1 pending

7.8. git-buildpackage

git-buildpackage 软件包提供了许多命令来使用 git 仓库自动打包。

  • gbp import-dsc:向 git 仓库中导入先前的 Debian 源码包。
  • gbp import-orig:向 git 仓库中导入新的上游源码。

    • git import-orig 命令的 --pristine-tar 选项允许将上游源码包储存在同一个 git 仓库中。
    • --uscan 选项作为 gbp import-orig 命令的最后一个参数会允许下载上游原始码并提交到 git 仓库中。
  • gbp dch:从 git 提交信息中生成 Debian 变更信息(changelog)。

  • gbp buildpackage:从 git 仓库中构建 Debian 二进制包。
  • gbp pull:从远程仓库中安全更新 debian, upstream and pristine-tar 分支。
  • git-pbuilder:使用 pbuilder 软件包从 git 仓库构建 Debian 二进制软件包。

    • 使用 cowbuilder 软件包作为后端。
  • gbp pqgit-dpmquilt(或者其别名 dquilt)命令用于管理兼容 quilt 的补丁。

    • dquilt 命令是学起来最简单的,它只要求您使用 git 命令手动提交最后的文件至 master 分支。
    • gbp pq” 命令提供了等效的补丁集管理功能,而不需要使用 dquilt 并且使用 git 的拣选(cherry-pick)功能简化了包含上游 git 仓库修改的操作流程。
    • git dpm” 命令提供了比 “gbp pq” 更强大的功能。

使用git-buildpackage软件包来管理软件包历史正成为绝大多数 Debian 维护者的实践标准。

参见:

[Tip]Tip

放松。您并不需要使用全部的打包工具,您只需要使用您所需要的那个就行。

7.8.1. gbp import-dscs —debsnap

对于记录在 snapshot.debian.org 归档中的名为 <source-package> 的 Debian 源码包,可以生成包含所有 Debian 版本历史的初始 git 存储库,如下所示。

  1. $ gbp import-dscs --debsnap --pristine-tar '<source-package>'

7.9. 上游 git 仓库

对于使用 git-buildpackage 打包的 Debian 软件包,远程存储库 origin 上的 upstream 分支通常用于跟踪已发布的上游原始码的内容。

也可以通过将其远程存储库命名为 upstream 而不是默认的 origin 来跟踪上游 git 仓库。 然后,您可以通过使用 gitk 命令和 gbp-pq 命令进行挑选,轻松地将最近的上游更改添加到 Debian 修订版中。

[Tip]Tip

gbp import-orig —upstream-vcs-tag” 命令可以通过使用上游 git 仓库中的指定标签在 upstream 分支上创建一个合并提交的方式来生成干净的打包历史信息。

[Caution]Caution

已发布的上游原始码的内容可能与上游 git 存储库的相应内容并不完全匹配。 它可能包含一些自动生成的文件或遗漏一些文件。(Autotools、distutils……)

7.10. chroot

The chroot for a clean package build environment can be created and managed using the tools described in Chapter 3, 工具的配置. [19]

以下是可用的软件包构建命令的快速总结。 有很多方法可以做同样的事情。

  • dpkg-buildpackage = 软件包打包工具的核心
  • debuild = dpkg-buildpackage + lintian (在清理后的环境变量下构建)
  • pbuilder = Debian chroot 环境工具的核心
  • pdebuild = pbuilder + dpkg-buildpackage (在 chroot 环境下构建)
  • cowbuilder = 提升 pbuilder 执行的速度
  • git-pbuilder = pdebuild 的易于使用的命令行语法(由 gbp buildpackge 使用)
  • gbp = 在 git 下管理 Debian 源代码
  • gbp buildpackge = pbuilder + dpkg-buildpackage + gbp

可以根据如下方式使用干净的 sid 版本的 chroot 环境。

  • 用于 sid 发行版的 chroot 文件系统创建命令

    • pbuilder create
    • git-pbuilder create
  • sid 版本的 chroot 文件系统的文件路径

    • /var/cache/pbuilder/base.cow
  • sid 发行版 chroot 的包构建命令

    • pdebuild
    • git-pbuilder
    • gbp buildpackage
  • 更新 sid chroot 的命令

    • pbuilder —update
    • git-pbuilder update
  • 要登录到 sid 修改 chroot 文件系统的命令

    • git-pbuilder login —save-after-login

可以根据如下方式使用任意的 dist 版本环境。

  • 用于 dist 版本的 chroot 文件系统创建命令

    • pbuilder create —distribution dist
    • DIST=*dist *git-pbuilder create
  • dist 版本的 chroot 文件系统的文件路径

    • path: /var/cache/pbuilder/base-*dist*.cow
  • dist 版本 chroot 的包构建命令

    • pdebuild — —basepath=/var/cache/pbuilder/base-*dist*.cow
    • DIST=*dist *git-pbuilder
    • gbp buildpackage —git-dist=*dist*
  • 更新 dist chroot 的命令

    • pbuilder update —basepath=/var/cache/pbuilder/base-*dist*.cow
    • DIST=*dist *git-pbuilder update
  • 登入 dist chroot 环境以进行修改的命令

    • pbuilder —login —basepath=/var/cache/pbuilder/base-*dist*.cow —save-after-login
    • DIST=*dist *git-pbuilder login —save-after-login
[Tip]Tip

使用这个“git-pbuilder login —save-after-login”命令可以非常方便地创建一个包含一些新实验包所需的预加载包的自定义环境。

[Tip]Tip

如果您的旧 chroot 文件系统缺少例如 libeatmydata1ccachelintian 等软件包,您可能需要使用“git-pbuilder login —save-after-login” 命令来安装这些软件包。

[Tip]Tip

只需使用 “cp -a base-dist.cow base-customdist.cow” 命令即可克隆 chroot 文件系统。 新的 chroot 可以以 “gbp buildpackage —git-dist=customdist” 和 “DIST=customdist git-pbuilder …” 访问。

[Tip]Tip

当需要为除 01 之外的 Debian 修订版上传 orig.tar.gz 文件时(例如,对于安全性上传),将 -sa 选项添加到 dpkg-buildpackagedebuildpdebuildgit-pbuilder 命令末尾。 对于 “gbp buildpackage” 命令,临时修改 ~/.gbp.conf 中的 builder 设置。

[Note]Note

本节中的描述过于简洁,对大多数潜在的维护者都没用。 这是作者的有意为之。 我们强烈建议您搜索并阅读与所用命令相关的所有文档。

7.11. 新的 Debian 版本

Let’s assume that a bug report #*bug_number was filed against your package, and it describes a problem that you can solve by editing the buggy file in the upstream source. Here’s what you need to do to create a new Debian revision of the package with the *bugname.patch file recording the fix.

使用 dquilt 命令准备新的 Debian 软件包修订版本.

  1. $ dquilt push -a
  2. $ dquilt new bugname.patch
  3. $ dquilt add buggy
  4. $ vim buggy
  5. ...
  6. $ dquilt refresh
  7. $ dquilt header -e
  8. $ dquilt pop -a
  9. $ dch -i

此外,如果软件包是用 git-buildpackage 命令以其默认配置管理的 git 仓库:

使用 gbp-pq 命令进行新的 Debian 修订.

  1. $ git checkout master
  2. $ gbp pq import
  3. $ vim buggy
  4. $ git add buggy
  5. $ git commit
  6. $ git tag pq/<newrev>
  7. $ gbp pq export
  8. $ gbp pq drop
  9. $ git add debian/patches/*
  10. $ dch -i
  11. $ git commit -a -m "Closes: #<bug_number>"

请确保简明扼要地描述修复报告错误的更改并通过在 debian/changelog 文件中添加 “Closes: #*<bug_number>”* 来关闭这些错误。

[Tip]Tip

在实验时使用带有版本字符串的 debian/changelog 条目,例如 1.0.1-1~rc1 。然后,将这些更改日志条目整理到官方软件包的条目中。

7.12. 新上游版本

如果 foo 包是以现代“3.0 (native)”或“3.0 (quilt)”格式正确打包的,则打包新的上游版本时需要将旧的 debian/ 目录移动到新的源码路径中。 这可以通过在新提取的源码路径中运行“tar -xvzf /path/to/foo_oldversion**.debian.tar.gz**”命令来完成。[20] 当然,你还需要做一些修改。

有很多的工具可以用以处理这些情况。在使用这些软件来更新上游版本后,请在 debian/changelog 文件中简要描述修复错误的上游修改,并添加 “Closes: #*bug_number”* 来关闭错误。

7.12.1. uupdate + tarball

您可以使用来自 uupdate 软件包中的 uupdate 命令来自动更新到新的上游源码。该命令需要旧的 Debian 源码包和新的上游源码包。

  1. $ wget https://example.org/foo/foo-newversion.tar.gz
  2. $ cd foo-oldversion
  3. $ uupdate -v newversion ../foo-newversion.tar.gz
  4. ...
  5. $ cd ../foo-newversion
  6. $ while dquilt push; do dquilt refresh; done
  7. $ dch

7.12.2. uscan

您可以使用来自 uupdate 软件包中的 uscan 命令来自动更新到新的上游源码。该命令需要包含 debian/watch 文件的旧的 Debian 源码包。

  1. $ cd foo-oldversion
  2. $ uscan
  3. ...
  4. $ while dquilt push; do dquilt refresh; done
  5. $ dch

7.12.3. gbp

您可以使用来自 git-buildpackage 软件包中的 “gbp import-orig —pristine-tar” 命令来自动更新到新的上游源码。该命令需要在 git 仓库中的 Debian 源码和新的上游源码包。

  1. $ ln -sf foo-newversion.tar.gz foo_newversion.orig.tar.gz
  2. $ cd foo-vcs
  3. $ git checkout master
  4. $ gbp pq import
  5. $ git checkout master
  6. $ gbp import-orig --pristine-tar ../foo_newversion.orig.tar.gz
  7. ...
  8. $ gbp pq rebase
  9. $ git checkout master
  10. $ gbp pq export
  11. $ gbp pq drop
  12. $ git add debian/patches
  13. $ dch -v <newversion>
  14. $ git commit -a -m "Refresh patches"
[Tip]Tip

如果上游也使用 git 仓库,请为 gbp import-orig 命令加上 —upstream-vcs-tag 选项。

7.12.4. gbp + uscan

您可以使用来自 git-buildpackage 软件包中的“gbp import-orig —pristine-tar —uscan”命令来自动更新到新的上游源码。该命令需要在 git 仓库中的包含 debian/watch 文件的 Debian 源码。

  1. $ cd foo-vcs
  2. $ git checkout master
  3. $ gbp pq import
  4. $ git checkout master
  5. $ gbp import-orig --pristine-tar --uscan
  6. ...
  7. $ gbp pq rebase
  8. $ git checkout master
  9. $ gbp pq export
  10. $ gbp pq drop
  11. $ git add debian/patches
  12. $ dch -v <newversion>
  13. $ git commit -a -m "Refresh patches"
[Tip]Tip

如果上游也使用 git 仓库,请为 gbp import-orig 命令加上 —upstream-vcs-tag 选项。

7.13. 3.0 源代码格式

更新软件包的风格并不是更新软件包所必须的步骤。但是,这么做可以让您充分利用现代 debhelper3.0 源码格式的所有能力。

  • 如果您因任何原因需要重新创建已删除的模板文件,您可以在同一个 Debian 软件包源码树中再次运行 debmake。然后适当地编辑它们。- 如果软件包还未更新到可为 debian/rules 文件使用 dh 命令,请升级它以便使用该命令(参见 Section 5.4.2, “简单的 debian/rules”)。请根据具体情况更新 debian/control 文件。
  • 如果你有一个带有 foo.diff.gz 文件的 1.0 格式的源码包,你可以通过创建带有“3.0 (quilt)”的 debian/source/format 文件来升级至新的 “3.0 (quilt)”格式。剩下的 debian/* 文件可以直接复制。如果需要的话,可以将“filterdiff -z -x */debian/* foo.diff.gz > big.diff”命令生成的 big.diff 文件导入到你的 quilt 系统中。[21]
  • 如果它使用了其他的补丁系统,例如 dpatchdbs 或者是带有 -p0-p1-p2 参数的 cdbs。请使用 quilt 包中的 deb3 脚本来转换它。
  • 如果它使用了带有 “--with quilt” 选项的 dh 命令或者使用了 dh_quilt_patchdh_quilt_unpatch 命令,请移除这些并且使其使用新的 “3.0 (quilt)” 格式。
  • 如果您有一个不带 foo.diff.gz 文件的 1.0 格式的源码包,您可以通过创建包含“3.0 (native)”的 debian/source/format 文件,然后将其余的 debian/* 文件直接复制的方式来更新至新的“3.0 (native)”的源码格式。

您应该核对一下 DEP——Debian 增强提议 并且采用已接受的提议。

参见 ProjectsDebSrc3.0 以核对 Debian 工具链对新 Debian 源码格式的支持情况。

7.14. CDBS

Common Debian Build System (CDBS)是 debhelper 软件包的包装系统。CDBS 基于 Makefile 包含机制并且由 debian/rules 文件中设置的 DEB_* 变量配置。

在将 dh 命令引入第七版的 debhelper 软件包之前,CDBS 是创建简单干净的 debian/rules 文件的唯一方法。

对于很多简单的软件包,现在 dh 命令使 debian/rules 文件很简洁,建议保持构建系统简洁,而非使用冗长的 CDBS

[Note]Note

CDBS 神奇地让我用更少的命令来完成工作”和“我不懂新的 dh 的语法”都不是您继续使用旧的 CDBS 系统的借口。

对于一些复杂的软件包,比如与 GNOME 相关的,当前的维护者有理由利用 CDBS 自动化完成他们的统一包装。如果是这种情况,请不要费心从 CDBS 转换为 dh 语法。

[Note]Note

如果您正在与维护 团队 合作,请遵循团队的既定惯例。

将软件包从 CDBS 转换为 dh 语法时,请使用以下内容作为参考:

7.15. 在 UTF-8 环境下构建

构建环境的默认语言环境是 C

某些程序(如 Python3 的 read 函数)会根据区域设置改变行为。

添加以下代码到 debian/rules 文件可以确保程序使用 C.UTF-8 的区域语言设置(locale)进行构建。

  1. LC_ALL := C.UTF-8
  2. export LC_ALL

7.16. UTF-8 转换

如果上游文档是用旧编码方案编码的,那么将它们转换为 UTF-8 是个好主意。

请使用 libc-bin 包中的 iconv 命令来转换纯文本文件的编码。

  1. $ iconv -f latin1 -t utf8 foo_in.txt > foo_out.txt

使用 w3m(1) 将 HTML 文件转换为 UTF-8 纯文本文件。 执行此操作时,请确保在 UTF-8 语言环境下执行它。

  1. $ LC_ALL=C.UTF-8 w3m -o display_charset=UTF-8 \
  2. -cols 70 -dump -no-graph -T text/html \
  3. < foo_in.html > foo_out.txt

debian/rules 文件的 override_dh_* 目标中运行这些脚本。

7.17. 上传 orig.tar.gz

当您第一次向归档上传软件包时,您还需要包含原始的 orig.tar.gz 源码。

如果 Debian 修订码是 1 或者 0,这都是默认的。否则,您必须使用带有 -sa 选项的 dpkg-buildpackage 命令。

  • dpkg-buildpackage -sa
  • debuild -sa
  • pdebuild —debbuildopts -sa
  • git-pbuilder -sa
  • 对于 gbp buildpackage,请编辑 ~/.gbp.conf 文件。
[Tip]Tip

另一方面,-sd 选项将会强制排除原始的 orig.tar.gz 源码。

[Tip]Tip

添加至 ~/.bashrc 文件。

7.18. 跳过的上传

如果当跳过上传时,你在 debian/changelog 中创建了多个条目,你必须创建一个包含自上次上传以来所有变更的 debian/changelog 文件。这可以通过指定 dpkg-buildpackage 选项 -v 以及上次上传的版本号,比如 1.2 来完成。

  • dpkg-buildpackage -v*1.2*
  • debuild -v*1.2*
  • pdebuild —debbuildopts -v*1.2*
  • git-pbuilder -v*1.2*
  • 对于 gbp buildpackage,请编辑 ~/.gbp.conf 文件。

7.19. 高级打包

关于以下内容的提示可以在 debhelper(7) 手册页中找到:

  • debhelper 工具在 “compat <= 8” 选项下不同的行为
  • 在数种不同构建条件下构建多种二进制包

    • 制作上游源码的多个副本
    • override_dh_auto_configure 目标中调用多个 “dh_auto_configure -S …” 指令
    • override_dh_auto_build 目标中调用多个 “dh_auto_build -S …” 指令
    • override_dh_auto_install 目标中调用多个 “dh_auto_install -S …” 指令
    • building udeb packages with “Package-Type: udeb” in debian/control (see Package-Type)
  • 从引导进程中排除某些包(参见 BuildProfileSpec

    • debian/control 中的二进制包节中添加 Build-Profiles 字段
    • DEB_BUILD_PROFILES 环境变量设置成相关配置文件名的条件下构建软件包

关于以下内容的提示可以在 dpkg-source(1) 手册页中找到:

  • 多个上游源码包的命名约定

    • 软件包名_版本**.orig.tar.gz**
    • 软件包名_版本**.orig-部件名.tar.gz**
  • 将 Debian 更改记录到上游源码包中

    • dpkg-source —commit

7.20. 其他发行版

尽管上游的原始码有着所有构建 Debian 软件包所需的信息,找出使用何种选项的组合仍然不是一件简单的事。

此外,上游的包可能更专注于功能的增强,而并不那么重视向后兼容性等特性,这是 Debian 打包实践中的一个重要方面。

利用其他发行版的信息是解决上述问题的一种选择。

如果其他发行版是由 Debian 派生的,重新使用它是没有价值的。

如果其他发行版是基于 RPM 的发行版,请参见 Repackage src.rpm

通过 rget 命令,可以下载并打开 src.rpm文件。(请将 rget 脚本添加至 PATH 中)

rget 脚本.

  1. #!/bin/sh
  2. FCSRPM=$(basename $1)
  3. mkdir ${FCSRPM}; cd ${FCSRPM}/
  4. wget $1
  5. rpm2cpio ${FCSRPM} | cpio -dium

许多上游源码包包含 RPM 系统使用的、以 packagename.spec 或者 packagename.spec.in 命名的SPEC 文件。这可以被用做 Debian 软件包的基点。

7.21. 除错

当您遇到构建问题或者生成的二进制程序核心转储时,您需要自行解决他们。这就是除错(debug)

This is too deep a topic to describe here. So, let me just list few pointers and hints for some typical debug tools.

  • 核心转储

    • man core
    • 更新 “/etc/security/limits.conf” 文件来包含以下代码:

      1. * soft core unlimited
    • ~/.bashrc 中添加“ulimit -c unlimited

    • 使用 “ulimit -a” 来检查
    • 按下 Ctrl-\ 或者“kill -ABRT PID” 来建立一个核心转储文件
  • gdb - The GNU Debugger

    • info gdb
    • 参见 /usr/share/doc/gdb-doc/html/gdb/index.html 中的 “Debugging with GDB”
  • strace - 跟踪系统调用和信号

    • 使用 /usr/share/doc/strace/examples/ 中的 strace-graph 脚本来建立一个好看的树形图
    • man strace
  • ltrace - 跟踪库调用

    • man ltrace
  • sh -n script.sh” - Shell 脚本的语法检查

  • sh -x script.sh” - 跟踪 Shell 脚本
  • python -m py_compile script.py” - Python 脚本的语法检查
  • python -mtrace —trace script.py” - 跟踪 Python 脚本
  • perl -I ../libpath -c script.pl” - Perl 脚本的语法检查
  • perl -d:Trace script.pl” - 跟踪 Perl 脚本

    • 安装 libterm-readline-gnu-perl 软件包或者同类型软件来添加输入行编辑功能与历史记录支持。
  • lsof - 按进程列出打开的文件

    • man lsof
[Tip]Tip

script 命令能帮助记录控制台输出。

[Tip]Tip

ssh 命令中搭配使用 screentmux 命令,能够提供安全并且强健的远程连接终端。

[Tip]Tip

libreply-perl(新的)软件包和来自 libdevel-repl-perl(旧的)软件包的 re.pl 命令为 Perl 提供了一个类似 Python 和 Shell 的 REPL (=READ + EVAL + PRINT + LOOP) 环境。

[Tip]Tip

rlwraprlfe 命令为所有交互命令提供了输入行编辑功能。例如 “rlwrap dash -i”。


[19] The git-pbuilder style organization is deployed here. See https://wiki.debian.org/git-pbuilder . Be careful since many HOWTOs use different organization.

[20] 如果 foo 包是以旧的 1.0 格式打包的,则相对的,只要在新的源代码路径中执行“zcat /path/to/foo_oldversion**.diff.gz|patch -p1**”命令。

[21] 您可以使用 splitdiff 命令来将 big.diff 文件分割成多个小的增量更新补丁文件。