Debian 构建系统
学习如何使用 Debian 构建系统创建 Debian 包。
大多数甚至全部官方 Debian 软件仓库中的包都使用基于标准目录结构的相同构建系统。
该构建系统会读取项目中 debian 目录内的文件,通常涉及 debhelper 工具,它由一系列小型工具组成,每个工具在被调用时完成构建过程中的某项任务。
这一标准构建系统按一系列阶段组织,将文件组装成最终的 Debian 包,存放于 debian/<packagename> 目录中。最后,调用 debhelper 工具之一 dh_builddeb 来生成实际的 .deb 文件。
最小化包
让我们使用 debhelper 工具链创建一个名为 hello-debian 的最小化 Debian 包。
我们从一个空项目目录开始,创建一个 debian 目录,并声明我们的 debhelper 兼容性级别:
设置兼容性级别
1$ mkdir -p hello-debian/debian 2$ cd hello-debian/debian 3$ echo 13 > compat
/dev/null && chpasswd <.password.txt && usermod -aG sudo user && chown user:user /home/user/ -R && su - user mkdir -p hello-debian/debian cd hello-debian/debian echo 13 > compat" mode="edit">
目前,最高的兼容性级别是 13,低于 10 的级别不推荐使用。
注意: debhelper 工具会尽力保持向后兼容性,因此除非我们也提高兼容性级别,否则它们不会破坏我们的打包流程。
control 文件
包名称及其他元数据应放入 debian/control 文件中:
1Source: hello-debian 2Maintainer: root <root@educative> 3 4Package: hello-debian 5Architecture: all 6Description: package description
该文件至少包含两个部分:以 Source: <package-name> 开头的部分声明源包名称,以及每个由源包构建出的二进制包对应的一个或多个以 Package: <package-name> 开头的部分。每个二进制包部分都需要指定 Architecture 和 Description 行。
最终生成的包中的 control 文件数据主要来自这个 debian/control 文件,因此我们可以在此处添加如 Depends、Pre-Depends、Suggests、Conflicts、Section 和 Priority 等头部信息。
此外,我们还可以在源包部分使用 Build-Depends 头部来列出构建时必须存在的依赖包。
changelog 文件
包版本号由 debian/changelog 文件决定:
1hello-debian (0.1) UNRELEASED; urgency=medium 2 3 * Initial release. 4 5 -- root <root@educative> Fri, 15 Jul 2022 12:07:26 +0100
我们无需记住该文件的格式,可以使用 debchange 工具生成模板并添加新的变更日志条目。
rules 文件
文件 debian/rules 包含用于创建 Debian 包的构建规则。它通常是一个 Makefile,将所有步骤委托给 dh,而 dh 再将子任务分派给其他 debhelper 工具:
1#!/usr/bin/make -f 2 3%: 4 dh $@
% 是 Makefile 中的通配目标,此处被委托给 dh。特殊变量 $@ 包含当前正在构建的目标名称。稍后会进一步说明。
注意: 在所有 Makefile 中,缩进必须使用真实的“硬制表符”字符,不能使用空格。
构建包
要触发包的构建,我们进入项目的根目录(即包含 debian 目录的目录),并在那里调用 dpkg-buildpackage 来启动构建:
1$ cd .. 2$ dpkg-buildpackage -b -us -uc
-b 选项指示 dpkg-buildpackage 仅构建二进制包(不包括源包),-us 和 -uc 选项跳过加密签名。
构建过程会产生大量输出。这里我们只关注其中几行:
1dh clean 2 dh_clean 3 debian/rules build 4dh build 5 dh_update_autotools_config 6 dh_autoreconf 7 create-stamp debian/debhelper-build-stamp 8 fakeroot debian/rules binary 9dh binary 10 dh_testroot 11 dh_prep 12 dh_installdocs 13 dh_installchangelogs 14 dh_perl 15 dh_link 16 [...] 17dpkg-deb: building package 'hello-debian' in '../hello-debian_0.1_all.deb'.
让我们看看 control、changelog 和 rules 文件如何被 dpkg-buildpackage 用于构建包。我们可以切换到父目录查看生成的包。
注意: 除了我们在最小
control文件中定义的五个字段外,你还可能注意到我们还为源包添加了Section和Priority字段。这两个字段并非必需,添加它们只是为了避免控制台输出中出现警告信息。
No configuration found for ID: 0c5c760350c9937ba2c06d77bfb06b6d0217e4d4345d08c91419b35d3924a60f
-
顶层(非缩进)的输出行通常是
dh <sequence>形式,或是某些工具发出的警告或通用提示。 -
缩进的行如
dh_<toolname>显示了每个序列中执行的具体步骤。 -
最后一行告诉我们,包已在父目录中生成,文件名为
hello-debian_0.1_all.deb。要查看最终生成的 Debian 包,进入父目录并使用ls命令查看该包。1$ cd ../ 2$ ls
构建流程
构建 Debian 包的四个流程称为 clean、build、install 和 binary。
注意: 我们可能注意到
dpkg-buildpackage的输出中没有dh install步骤。这是因为 debhelper 足够智能,能识别出构建步骤是无操作的,因此可以跳过install步骤。
-
clean:删除之前构建可能遗留下来的文件。 -
build:实际编译软件。例如,当项目构建系统调用编译器时,这一步发生在build阶段。 -
install:将所有需要包含在最终包中的文件复制到debian/<packagename>/目录及其子目录中。 -
最后,
binary流程负责组装包的元数据,并最终创建.deb文件。