Chapter 4. 简单例子

有一句古罗马谚语说得好:“Longum iter est per praecepta, breve et efficax per exempla”(“一例胜千言!”)。

这里给出了从简单的 C 语言源代码创建简单的 Debian 软件包的例子,并假设上游使用了 Makefile 作为构建系统。

我们假设上游源码压缩包(tarball)名称为 debhello-0.0.tar.gz

这一类源代码设计可以用这样的方式安装成为非系统文件:

  1. $ tar -xzmf debhello-0.0.tar.gz
  2. $ cd debhello-0.0
  3. $ make
  4. $ make install

Debian 的打包需要对“make install”流程进行改变,从而将文件安装至目标系统镜像所在位置,而非通常使用的 /usr/local 下的位置。

[Note]Note

在其它更加复杂的构建系统下构建 Debian 软件包的例子可以在 Chapter 8, 更多示例 找到。

4.1. 大致流程

从上游源码压缩包 debhello-0.0.tar.gz 构建单个非本土 Debian 软件包的大致流程可以总结如下:

  • 维护者获取上游源码压缩包 debhello-0.0.tar.gz 并将其内容解压缩至 debhello-0.0 目录中。
  • debmake 命令对上游源码树进行 debian 化(debianize),具体来说,是创建一个 debian 目录并仅向该目录中添加各类模板文件。

    • 名为 debhello_0.0.orig.tar.gz 的符号链接被创建并指向 debhello-0.0.tar.gz 文件。
    • 维护者须自行编辑修改模板文件。
  • debuild 命令基于已 debian 化的源码树构建二进制软件包。

    • debhello-0.0-1.debian.tar.xz 将被创建,它包含了 debian 目录。

软件包构建的大致流程.

  1. $ tar -xzmf debhello-0.0.tar.gz
  2. $ cd debhello-0.0
  3. $ debmake
  4. ... manual customization
  5. $ debuild
  6. ...
[Tip]Tip

此处和下面例子中的 debuild 命令可使用等价的命令进行替换,例如 pdebuild 命令。

[Tip]Tip

如果上游源码压缩包提供了 .tar.xz 格式文件,请使用这样的压缩包来替代 .tar.gz.tar.bz2 格式。xz 压缩与 gzipbzip2 压缩相比提供了更好的压缩比。

4.2. 什么是 debmake?

文中的 debmake 命令是用于 Debian 打包的一个帮助脚本。

  • 它总是将大多数选项的状态与参数设置为合理的默认值。
  • 它能产生上游源码包,并按需创建所需的符号链接。
  • 它不会覆写 debian/ 目录下已存在的配置文件。
  • 它支持多架构(multiarch)软件包。
  • 它能创建良好的模板文件,例如符合 DEP-5debian/copyright 文件。

这些特性使得使用 debmake 进行 Debian 打包工作变得简单而现代化。

[Note]Note

debmake 命令并不是制作一个 Debian 软件包的唯一途径。许多软件包是打包者模仿其它已有的打包示例,仅仅使用文本编辑器而编写完成打包脚本的。

4.3. 什么是 debuild?

这里给出与 debuild 命令类似的一系列命令的一个汇总。

  • debian/rules 文件定义了 Debian 二进制软件包该如何构建。- dpkg-buildpackge 是构建 Debian 二进制软件包的正式命令。对于正常的二进制构建,它大体上会执行以下操作:

    • dpkg-source —before-build”(应用 Debian 补丁,除非它们已被应用)
    • fakeroot debian/rules clean
    • dpkg-source —build”(构建 Debian 源码包)
    • fakeroot debian/rules build
    • fakeroot debian/rules binary
    • dpkg-genbuildinfo”(产生一个 *.buildinfo 文件)
    • dpkg-genchanges”(产生一个 *.changes 文件)
    • fakeroot debian/rules clean
    • dpkg-source —after-build”(取消 Debian 补丁,如果它们在 --before-build 阶段已被应用)- “debsign”(对 *.dsc*.changes 文件进行签名)

      • 如果您按照 Section 3.5, “devscripts” 的说明设置了 -us-us 选项的话,本步骤将会被跳过。您需要手动运行 debsign 命令。
  • debuild 命令是 dpkg-buildpackage 命令的一个封装脚本,它可以使用合适的环境变量来构建 Debian 二进制软件包。

  • pdebuild 命令是另一个封装脚本,它可以在合适的 chroot 环境下使用合适的环境变量构建 Debian 二进制软件包。
  • git-pbuilder 命令是又一个用于构建 Debian 二进制软件包的封装脚本,它同样可以确保使用合适的环境变量和 chroot 环境。不同之处在于它提供了一个更容易使用的命令行用户界面,可以较方便地在不同的构建环境之间进行切换。
[Note]Note

如需了解详细内容,请见 dpkg-buildpackage(1)。

4.4. 第一步:获取上游源代码

我们先要获取上游源代码。

下载 debhello-0.0.tar.gz.

  1. $ wget http://www.example.org/download/debhello-0.0.tar.gz
  2. ...
  3. $ tar -xzf debhello-0.0.tar.gz
  4. $ tree
  5. .
  6. ├── debhello-0.0
  7. ├── LICENSE
  8. ├── Makefile
  9. └── src
  10. └── hello.c
  11. └── debhello-0.0.tar.gz
  12. 2 directories, 4 files

这里的 C 源代码 hello.c 非常的简单。

**hello.c.**

  1. $ cat debhello-0.0/src/hello.c
  2. #include <stdio.h>
  3. int
  4. main()
  5. {
  6. printf("Hello, world!\n");
  7. return 0;
  8. }

这里,源码中的 Makefile 支持 GNU 编码标准FHS(文件系统层级规范)。特别地:

  • 构建二进制程序时会考虑 $(CPPFLAGS)$(CFLAGS)$(LDFLAGS),等等。
  • 安装文件时采纳 $(DESTDIR) 作为目标系统镜像的路径前缀
  • 安装文件时使用 $(prefix) 的值,以便我们将其设置覆盖为 /usr

**Makefile.**

  1. $ cat debhello-0.0/Makefile
  2. prefix = /usr/local
  3. all: src/hello
  4. src/hello: src/hello.c
  5. @echo "CFLAGS=$(CFLAGS)" | \
  6. fold -s -w 70 | \
  7. sed -e 's/^/# /'
  8. $(CC) $(CPPFLAGS) $(CFLAGS) $(LDCFLAGS) -o $@ $^
  9. install: src/hello
  10. install -D src/hello \
  11. $(DESTDIR)$(prefix)/bin/hello
  12. clean:
  13. -rm -f src/hello
  14. distclean: clean
  15. uninstall:
  16. -rm -f $(DESTDIR)$(prefix)/bin/hello
  17. .PHONY: all install clean distclean uninstall
[Note]Note

$(CFLAGS)echo 命令用于在接下来的例子中验证所设置的构建参数。

4.5. 第二步:使用 debmake 产生模板文件

[Tip]Tip

如果 debmake 命令调用时使用了 -T 选项,程序将为模板文件产生更加详细的注释内容。

debmake 命令的输出十分详细,如下所示,它可以展示程序的具体操作内容。

  1. $ cd debhello-0.0
  2. $ debmake
  3. I: set parameters
  4. I: sanity check of parameters
  5. I: pkg="debhello", ver="0.0", rev="1"
  6. I: *** start packaging in "debhello-0.0". ***
  7. I: provide debhello_0.0.orig.tar.gz for non-native Debian package
  8. I: pwd = "/path/to"
  9. I: $ ln -sf debhello-0.0.tar.gz debhello_0.0.orig.tar.gz
  10. I: pwd = "/path/to/debhello-0.0"
  11. I: parse binary package settings:
  12. I: binary package=debhello Type=bin / Arch=any M-A=foreign
  13. I: analyze the source tree
  14. I: build_type = make
  15. I: scan source for copyright+license text and file extensions
  16. I: 100 %, ext = c
  17. I: check_all_licenses
  18. I: ..
  19. I: check_all_licenses completed for 2 files.
  20. I: bunch_all_licenses
  21. I: format_all_licenses
  22. I: make debian/* template files
  23. I: single binary package
  24. I: debmake -x "1" ...
  25. I: creating => debian/control
  26. I: creating => debian/copyright
  27. I: substituting => /usr/share/debmake/extra0/changelog
  28. I: creating => debian/changelog
  29. I: substituting => /usr/share/debmake/extra0/rules
  30. I: creating => debian/rules
  31. I: substituting => /usr/share/debmake/extra1/watch
  32. I: creating => debian/watch
  33. I: substituting => /usr/share/debmake/extra1/README.Debian
  34. I: creating => debian/README.Debian
  35. I: substituting => /usr/share/debmake/extra1source/format
  36. I: creating => debian/source/format
  37. I: substituting => /usr/share/debmake/extra1source/local-options
  38. I: creating => debian/source/local-options
  39. I: substituting => /usr/share/debmake/extra1patches/series
  40. I: creating => debian/patches/series
  41. I: run "debmake -x2" to get more template files
  42. I: $ wrap-and-sort

debmake 命令基于命令行选项产生所有这些模板文件。如果没有指定具体选项,debmake 命令将为您自动选择合理的默认值:

  • 源码包名称:debhello
  • 上游版本:0.0
  • 二进制软件包名称:debhello
  • Debian 修订版本:1
  • 软件包类型: bin(ELF 二进制可执行程序软件包)
  • -x 选项:-x1(是单个二进制软件包的默认值)

我们来检查一下自动产生的模板文件。

基本 debmake 命令运行后的源码树。.

  1. $ cd ..
  2. $ tree
  3. .
  4. ├── debhello-0.0
  5. ├── LICENSE
  6. ├── Makefile
  7. ├── debian
  8. ├── README.Debian
  9. ├── changelog
  10. ├── control
  11. ├── copyright
  12. ├── patches
  13. └── series
  14. ├── rules
  15. ├── source
  16. ├── format
  17. └── local-options
  18. └── watch
  19. └── src
  20. └── hello.c
  21. ├── debhello-0.0.tar.gz
  22. └── debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz
  23. 5 directories, 14 files

这里的 debian/rules 文件是应当由软件包维护者提供的构建脚本。此时该文件是由 debmake 命令产生的模板文件。

**debian/rules(模板文件):.**

  1. $ cat debhello-0.0/debian/rules
  2. #!/usr/bin/make -f
  3. # You must remove unused comment lines for the released package.
  4. #export DH_VERBOSE = 1
  5. #export DEB_BUILD_MAINT_OPTIONS = hardening=+all
  6. #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
  7. #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
  8. %:
  9. dh $@
  10. #override_dh_auto_install:
  11. # dh_auto_install -- prefix=/usr
  12. #override_dh_install:
  13. # dh_install --list-missing -X.pyc -X.pyo

这便是使用 dh 命令时标准的 debian/rules 文件。(某些内容已被注释,可供后续修改使用。)

这里的 debian/control 文件提供了 Debian 软件包的主要元信息。此时该文件是由 debmake 命令产生的模板文件。

**debian/control(模板文件):.**

  1. $ cat debhello-0.0/debian/control
  2. Source: debhello
  3. Section: unknown
  4. Priority: optional
  5. Maintainer: "Firstname Lastname" <email.address@example.org>
  6. Build-Depends: debhelper-compat (= 13)
  7. Standards-Version: 4.5.0
  8. Homepage: <insert the upstream URL, if relevant>
  9. Package: debhello
  10. Architecture: any
  11. Multi-Arch: foreign
  12. Depends: ${misc:Depends}, ${shlibs:Depends}
  13. Description: auto-generated package by debmake
  14. This Debian binary package was auto-generated by the
  15. debmake(1) command provided by the debmake package.
[Warning]Warning

如果您对 debian/control 模板文件中的“Section: unknown”部分不做修改的话,后续的 lintian 错误可能导致构建失败。

因为这是个 ELF 二进制可执行文件软件包,debmake 命令设置了“Architecture: any”和“Multi-Arch: foreign”两项。同时,它将所需的 substvar 参数设置为“Depends: ${shlibs:Depends}, ${misc:Depends}”。这些内容将在 Chapter 5, 基本内容 部分进行解释。

[Note]Note

Please note this debian/control file uses the RFC-822 style as documented in 5.2 Source package control files — debian/control of the “Debian Policy Manual”. The use of the empty line and the leading space are significant.

这里的 debian/copyright 提供了 Debian 软件包版权数据的总结。此时该文件是由 debmake 命令产生的模板文件。

**debian/copyright(模板文件):.**

  1. $ cat debhello-0.0/debian/copyright
  2. Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
  3. Upstream-Name: debhello
  4. Upstream-Contact: <preferred name and address to reach the upstream project>
  5. Source: <url://example.com>
  6. #
  7. # Please double check copyright with the licensecheck(1) command.
  8. Files: Makefile
  9. src/hello.c
  10. Copyright: __NO_COPYRIGHT_NOR_LICENSE__
  11. License: __NO_COPYRIGHT_NOR_LICENSE__
  12. #----------------------------------------------------------------------------...
  13. # Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following
  14. # license/copyright files.
  15. #----------------------------------------------------------------------------...
  16. # License file: LICENSE
  17. License:
  18. .
  19. All files in this archive are licensed under the MIT License as below.
  20. .
  21. Copyright 2015 Osamu Aoki <osamu@debian.org>
  22. .
  23. Permission is hereby granted, free of charge, to any person obtaining a
  24. copy of this software and associated documentation files (the "Software"),
  25. to deal in the Software without restriction, including without limitation
  26. the rights to use, copy, modify, merge, publish, distribute, sublicense,
  27. and/or sell copies of the Software, and to permit persons to whom the
  28. Software is furnished to do so, subject to the following conditions:
  29. .
  30. The above copyright notice and this permission notice shall be included
  31. in all copies or substantial portions of the Software.
  32. .
  33. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  34. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  35. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  36. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  37. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  38. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  39. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4.6. 第三步:编辑模板文件

作为维护者,要制作一个合适的 Debian 软件包当然需要对模板内容进行一些手工的调整。

为了将安装文件变成系统文件的一部分,Makefile 文件中 $(prefix) 默认的 /usr/local 的值需要被覆盖为 /usr。要做到这点,可以按照下面给出的方法,在 debian/rules 文件中添加名为 override_dh_auto_install 的目标,在其中设置“prefix=/usr”。

**debian/rules(维护者版本):.**

  1. $ vim debhello-0.0/debian/rules
  2. ... hack, hack, hack, ...
  3. $ cat debhello-0.0/debian/rules
  4. #!/usr/bin/make -f
  5. export DH_VERBOSE = 1
  6. export DEB_BUILD_MAINT_OPTIONS = hardening=+all
  7. export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
  8. export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
  9. %:
  10. dh $@
  11. override_dh_auto_install:
  12. dh_auto_install -- prefix=/usr

如上在 debian/rules 文件中导出=DH_VERBOSE 环境变量可以强制 debhelper 工具输出细粒度的构建报告。

如上导出 DEB_BUILD_MAINT_OPTION 变量可以如 dpkg-buildflags(1) 手册页中“FEATURE AREAS/ENVIRONMENT”部分所说,对加固选项进行设置。[8]

如上导出 DEB_CFLAGS_MAINT_APPEND 可以强制 C 编译器给出所有类型的警告内容。

如上导出 DEB_LDFLAGS_MAINT_APPEND 可以强制链接器只对真正需要的库进行链接。[9]

对基于 Makefile 的构建系统来说,dh_auto_install 命令所做的基本上就是“$(MAKE) install DESTDIR=debian/debhello”。这里创建的 override_dh_auto_install 目标将其行为修改为“$(MAKE) install DESTDIR=debian/debhello prefix=/usr”。

这里是维护者版本的 debian/controldebian/copyright 文件。

**debian/control(维护者版本):.**

  1. $ vim debhello-0.0/debian/control
  2. ... hack, hack, hack, ...
  3. $ cat debhello-0.0/debian/control
  4. Source: debhello
  5. Section: devel
  6. Priority: optional
  7. Maintainer: Osamu Aoki <osamu@debian.org>
  8. Build-Depends: debhelper-compat (= 13)
  9. Standards-Version: 4.3.0
  10. Homepage: https://salsa.debian.org/debian/debmake-doc
  11. Package: debhello
  12. Architecture: any
  13. Multi-Arch: foreign
  14. Depends: ${misc:Depends}, ${shlibs:Depends}
  15. Description: example package in the debmake-doc package
  16. This is an example package to demonstrate Debian packaging using
  17. the debmake command.
  18. .
  19. The generated Debian package uses the dh command offered by the
  20. debhelper package and the dpkg source format `3.0 (quilt)'.

**debian/copyright(维护者版本):.**

  1. $ vim debhello-0.0/debian/copyright
  2. ... hack, hack, hack, ...
  3. $ cat debhello-0.0/debian/copyright
  4. Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
  5. Upstream-Name: debhello
  6. Upstream-Contact: Osamu Aoki <osamu@debian.org>
  7. Source: https://salsa.debian.org/debian/debmake-doc
  8. Files: *
  9. Copyright: 2015 Osamu Aoki <osamu@debian.org>
  10. License: Expat
  11. Permission is hereby granted, free of charge, to any person obtaining a
  12. copy of this software and associated documentation files (the "Software"),
  13. to deal in the Software without restriction, including without limitation
  14. the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15. and/or sell copies of the Software, and to permit persons to whom the
  16. Software is furnished to do so, subject to the following conditions:
  17. .
  18. The above copyright notice and this permission notice shall be included
  19. in all copies or substantial portions of the Software.
  20. .
  21. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  22. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  24. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  25. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  26. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  27. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。

**debian/. 下面的模板文件(0.0 版):.**

  1. $ tree debhello-0.0/debian
  2. debhello-0.0/debian
  3. ├── README.Debian
  4. ├── changelog
  5. ├── control
  6. ├── copyright
  7. ├── patches
  8. └── series
  9. ├── rules
  10. ├── source
  11. ├── format
  12. └── local-options
  13. └── watch
  14. 2 directories, 9 files
[Tip]Tip

对于来自 debhelper 软件包的各个 dh_* 命令来说,它们在读取所使用的配置文件时通常把以 # 开头的行视为注释行。

4.7. 第四步:使用 debuild 构建软件包

您可以使用 debuild 或者等效的命令工具(参见 Section 4.3, “什么是 debuild?”)在这个源码树内构建一个非本土 Debian 软件包。命令的输出通常十分详细,如下所示,它会对构建中执行的操作进行解释。

  1. $ cd debhello-0.0
  2. $ debuild
  3. dpkg-buildpackage -us -uc -ui -i -i
  4. ...
  5. fakeroot debian/rules clean
  6. dh clean
  7. ...
  8. debian/rules build
  9. dh build
  10. dh_update_autotools_config
  11. dh_autoreconf
  12. dh_auto_configure
  13. install -d /path/to/debhello-0.0/debian/.debhelper/generated/_source/...
  14. dh_auto_build
  15. make -j4 "INSTALL=install --strip-program=true"
  16. make[1]: Entering directory '/path/to/debhello-0.0'
  17. # CFLAGS=-g -O2
  18. # -fdebug-prefix-map=/home/osamu/pub/salsa/debmake/debmake-doc/debhello-
  19. ...
  20. fakeroot debian/rules binary
  21. dh binary
  22. ...
  23. Now running lintian -i -I --show-overrides debhello_0.0-1_amd64.changes ...
  24. ...
  25. W: debhello: binary-without-manpage usr/bin/hello
  26. N:
  27. N: Each binary in /usr/bin, /usr/sbin, /bin, /sbin or /usr/games should
  28. N: have a manual page
  29. ...

这里验证了 CFLAGS 已经得到了更新,添加了 -Wall-pendatic 参数;这是我们先前在 DEB_CFLAGS_MAINT_APPEND 变量中所指定的。

根据 lintian 的报告,您应该如同后文中的例子那样(请见 Chapter 8, 更多示例)为软件包添加 man 手册页。我们这里暂且跳过这部分内容。

现在我们来看看成果如何。

**debhello 0.0 版使用 debuild 命令产生的文件:.**

  1. $ cd ..
  2. $ tree -FL 1
  3. .
  4. ├── debhello-0.0/
  5. ├── debhello-0.0.tar.gz
  6. ├── debhello-dbgsym_0.0-1_amd64.deb
  7. ├── debhello_0.0-1.debian.tar.xz
  8. ├── debhello_0.0-1.dsc
  9. ├── debhello_0.0-1_amd64.build
  10. ├── debhello_0.0-1_amd64.buildinfo
  11. ├── debhello_0.0-1_amd64.changes
  12. ├── debhello_0.0-1_amd64.deb
  13. └── debhello_0.0.orig.tar.gz -> debhello-0.0.tar.gz
  14. 1 directory, 9 files

您可以看见生成的全部文件。

  • debhello_0.0.orig.tar.gz 是指向上游源码压缩包的符号链接。
  • debhello_0.0-1.debian.tar.xz 包含了维护者生成的内容。
  • debhello_0.0-1.dsc 是 Debian 源码包的元数据文件。
  • debhello_0.0-1_amd64.deb 是 Debian 二进制软件包。
  • debhello-dbgsym_0.0-1_amd64.deb 是 Debian 的调试符号二进制软件包。另请参见 Section 5.17.1, “新的 -dbgsym 软件包(Stretch 9.0 或更新)”
  • debhello_0.0-1_amd64.build 是构建日志文件。
  • debhello_0.0-1_amd64.buildinfodpkg-genbuildinfo(1) 生成的元数据文件。
  • debhello_0.0-1_amd64.changes 是 Debian 二进制软件包的元数据文件。

debhello_0.0-1.debian.tar.xz 包含了 Debian 对上游源代码的修改,具体如下所示。

压缩文件 debhello_0.0-1.debian.tar.xz 的内容:.

  1. $ tar -tzf debhello-0.0.tar.gz
  2. debhello-0.0/
  3. debhello-0.0/LICENSE
  4. debhello-0.0/Makefile
  5. debhello-0.0/src/
  6. debhello-0.0/src/hello.c
  7. $ tar --xz -tf debhello_0.0-1.debian.tar.xz
  8. debian/
  9. debian/README.Debian
  10. debian/changelog
  11. debian/control
  12. debian/copyright
  13. debian/patches/
  14. debian/patches/series
  15. debian/rules
  16. debian/source/
  17. debian/source/format
  18. debian/watch

debhello_0.0-1_amd64.deb 包含了将要安装至目标系统中的文件。

debhello-debsym_0.0-1_amd64.deb 包含了将要安装至目标系统中的调试符号文件。

所有二进制包的包内容:.

  1. $ dpkg -c debhello-dbgsym_0.0-1_amd64.deb
  2. drwxr-xr-x root/root ... ./
  3. drwxr-xr-x root/root ... ./usr/
  4. drwxr-xr-x root/root ... ./usr/lib/
  5. drwxr-xr-x root/root ... ./usr/lib/debug/
  6. drwxr-xr-x root/root ... ./usr/lib/debug/.build-id/
  7. drwxr-xr-x root/root ... ./usr/lib/debug/.build-id/66/
  8. -rw-r--r-- root/root ... ./usr/lib/debug/.build-id/66/73e0826b1e8bd84f511bac...
  9. drwxr-xr-x root/root ... ./usr/share/
  10. drwxr-xr-x root/root ... ./usr/share/doc/
  11. lrwxrwxrwx root/root ... ./usr/share/doc/debhello-dbgsym -> debhello
  12. $ dpkg -c debhello_0.0-1_amd64.deb
  13. drwxr-xr-x root/root ... ./
  14. drwxr-xr-x root/root ... ./usr/
  15. drwxr-xr-x root/root ... ./usr/bin/
  16. -rwxr-xr-x root/root ... ./usr/bin/hello
  17. drwxr-xr-x root/root ... ./usr/share/
  18. drwxr-xr-x root/root ... ./usr/share/doc/
  19. drwxr-xr-x root/root ... ./usr/share/doc/debhello/
  20. -rw-r--r-- root/root ... ./usr/share/doc/debhello/README.Debian
  21. -rw-r--r-- root/root ... ./usr/share/doc/debhello/changelog.Debian.gz
  22. -rw-r--r-- root/root ... ./usr/share/doc/debhello/copyright

生成的依赖列表会给出所有二进制软件包的依赖。

生成的所有二进制软件包的依赖列表(v=0.0):.

  1. $ dpkg -f debhello-dbgsym_0.0-1_amd64.deb pre-depends \
  2. depends recommends conflicts breaks
  3. Depends: debhello (= 0.0-1)
  4. $ dpkg -f debhello_0.0-1_amd64.deb pre-depends \
  5. depends recommends conflicts breaks
  6. Depends: libc6 (>= 2.2.5)
[Caution]Caution

在将软件包上传至 Debian 仓库之前,仍然有很多细节需要进行处理。

[Note]Note

如果跳过了对 debmake 命令自动生成的配置文件的手工调整步骤,所生成的二进制软件包可能缺少有用的软件包描述信息,某些政策的要求也无法满足。这个不正式的软件包对于 dpkg 命令来说可以正常处理,也许这样对您本地的部署来说已经足够好了。

4.8. 第三步(备选):修改上游源代码

上面的例子中,在创建合适的 Debian 软件包时没有修改上游的源代码。

作为维护者,另一个备选的方案是对上游源代码做改动,如修改上游的 Makefile 以将 $(prefix) 的值设定为 /usr

打包操作基本上和上面的分步示例相同,除了在 Section 4.6, “第三步:编辑模板文件” 中的两点:

这个使用一系列补丁文件进行 Debian 打包的备选方案对于应对上游未来的改变可能不够健壮,但是在应对更为复杂的上游源代码时可以更灵活。(参见 Section 7.13, “3.0 源代码格式”。)

[Note]Note

对当前这个特定的打包场景,前文的 Section 4.6, “第三步:编辑模板文件” 中使用 debian/rules 文件的方式更好一些。但为了演示起见,此时我们先使用本节的方式继续操作。

[Tip]Tip

对更复杂的打包场景,可能需要同时应用 Section 4.6, “第三步:编辑模板文件”Section 4.8, “第三步(备选):修改上游源代码” 中的方式。

4.8.1. 使用 diff -u 处理补丁

这里我们使用 diff 命令创建一个 000-prefix-usr.patch 文件作为例子。

  1. $ cp -a debhello-0.0 debhello-0.0.orig
  2. $ vim debhello-0.0/Makefile
  3. ... hack, hack, hack, ...
  4. $ diff -Nru debhello-0.0.orig debhello-0.0 >000-prefix-usr.patch
  5. $ cat 000-prefix-usr.patch
  6. diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile
  7. --- debhello-0.0.orig/Makefile 2020-07-13 00:38:01.407949320 +0900
  8. +++ debhello-0.0/Makefile 2020-07-13 00:38:01.479947950 +0900
  9. @@ -1,4 +1,4 @@
  10. -prefix = /usr/local
  11. +prefix = /usr
  12. all: src/hello
  13. $ rm -rf debhello-0.0
  14. $ mv -f debhello-0.0.orig debhello-0.0

请注意,上游的源码树应当恢复到原始状态,补丁文件此时的名字为 000-prefix-usr.patch

这个 000-prefix-usr.patch 文件随后应当进行编辑以使其符合 DEP-3,并照如下方式移动至正确的位置。

  1. $ cd debhello-0.0
  2. $ echo '000-prefix-usr.patch' >debian/patches/series
  3. $ vim ../000-prefix-usr.patch
  4. ... hack, hack, hack, ...
  5. $ mv -f ../000-prefix-usr.patch debian/patches/000-prefix-usr.patch
  6. $ cat debian/patches/000-prefix-usr.patch
  7. From: Osamu Aoki <osamu@debian.org>
  8. Description: set prefix=/usr patch
  9. diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile
  10. --- debhello-0.0.orig/Makefile
  11. +++ debhello-0.0/Makefile
  12. @@ -1,4 +1,4 @@
  13. -prefix = /usr/local
  14. +prefix = /usr
  15. all: src/hello

4.8.2. 使用 dquilt 处理补丁

这里的例子使用 dquilt 命令(一个 quilt 程序的简单封装)创建 000-prefix-usr.patchdquilt 命令的语法和功能与 quilt(1) 命令相同,唯一的区别在于补丁存储在 debian/patches/ 目录中。

  1. $ cd debhello-0.0
  2. $ dquilt new 000-prefix-usr.patch
  3. Patch debian/patches/000-prefix-usr.patch is now on top
  4. $ dquilt add Makefile
  5. File Makefile added to patch debian/patches/000-prefix-usr.patch
  6. ... hack, hack, hack, ...
  7. $ head -1 Makefile
  8. prefix = /usr
  9. $ dquilt refresh
  10. Refreshed patch debian/patches/000-prefix-usr.patch
  11. $ dquilt header -e --dep3
  12. ... edit the DEP-3 patch header with editor
  13. $ tree -a
  14. .
  15. ├── .pc
  16. ├── .quilt_patches
  17. ├── .quilt_series
  18. ├── .version
  19. ├── 000-prefix-usr.patch
  20. ├── .timestamp
  21. └── Makefile
  22. └── applied-patches
  23. ├── LICENSE
  24. ├── Makefile
  25. ├── debian
  26. ├── README.Debian
  27. ├── changelog
  28. ├── control
  29. ├── copyright
  30. ├── patches
  31. ├── 000-prefix-usr.patch
  32. └── series
  33. ├── rules
  34. ├── source
  35. ├── format
  36. └── local-options
  37. └── watch
  38. └── src
  39. └── hello.c
  40. 6 directories, 19 files
  41. $ cat debian/patches/series
  42. 000-prefix-usr.patch
  43. $ cat debian/patches/000-prefix-usr.patch
  44. Description: set prefix=/usr patch
  45. Author: Osamu Aoki <osamu@debian.org>
  46. Index: debhello-0.0/Makefile
  47. ===================================================================
  48. --- debhello-0.0.orig/Makefile
  49. +++ debhello-0.0/Makefile
  50. @@ -1,4 +1,4 @@
  51. -prefix = /usr/local
  52. +prefix = /usr
  53. all: src/hello

这里,上游源码树中的 Makefile 文件没有恢复到原始状态的必要。在 Section 4.7, “第四步:使用 debuild 构建软件包” 描述的 Debian 打包过程中调用的 dpkg-source 命令能够理解由 dquilt 程序在 .pc/ 目录中记录的补丁应用情况。只要所有这些修改都是由 dquilt 命令完成的,那么 Debian 源码包就可以从经过修改的源码树中进行构建。

[Note]Note

如果 .pc/ 目录不存在,dpkg-source 命令就会假定没有应用任何补丁。这就是更为原始的补丁生成方法,例如 Section 4.8.1, “使用 diff -u 处理补丁” 中未生成 .pc/ 目录的情况下要求将上游源码树进行恢复的原因。

4.8.3. 使用 dpkg-source —commit 处理补丁

这里给出使用“dpkg-source —commit”命令生成 000-prefix-usr.patch 的例子。

我们先来编辑上游源代码。

  1. $ cd debhello-0.0
  2. $ vim Makefile
  3. ... hack, hack, hack, ...
  4. $ head -n1 Makefile
  5. prefix = /usr

我们来进行提交。

  1. $ dpkg-source --commit . 000-prefix-usr.patch
  2. ... editor to edit the DEP-3 patch header
  3. ...

我们来看看效果如何。

  1. $ cat debian/patches/series
  2. 000-prefix-usr.patch
  3. $ cat debian/patches/000-prefix-usr.patch
  4. Description: set prefix=/usr patch
  5. Author: Osamu Aoki <osamu@debian.org>
  6. Index: debhello-0.0/Makefile
  7. --- debhello-0.0.orig/Makefile
  8. +++ debhello-0.0/Makefile
  9. @@ -1,4 +1,4 @@
  10. -prefix = /usr/local
  11. +prefix = /usr
  12. all: src/hello
  13. $ tree -a
  14. .
  15. ├── .pc
  16. ├── .quilt_patches
  17. ├── .quilt_series
  18. ├── .version
  19. ├── 000-prefix-usr.patch
  20. ├── .timestamp
  21. └── Makefile
  22. └── applied-patches
  23. ├── LICENSE
  24. ├── Makefile
  25. ├── debian
  26. ├── README.Debian
  27. ├── changelog
  28. ├── control
  29. ├── copyright
  30. ├── patches
  31. ├── 000-prefix-usr.patch
  32. └── series
  33. ├── rules
  34. ├── source
  35. ├── format
  36. └── local-options
  37. └── watch
  38. └── src
  39. └── hello.c
  40. 6 directories, 19 files

这里,dpkg-source 命令完成了与 Section 4.8.2, “使用 dquilt 处理补丁” 一节中使用 dquilt 命令完全相同的流程。


[8] 这里的做法是为了进行加固而强制启用只读重定位链接,以此避免 lintian 的警告“W: debhello: hardening-no-relro usr/bin/hello”。其实它在本例中并不是必要的,但加上也没有什么坏处。对于没有外部链接库的本例来说,lintian 似乎给出了误报的警告。

[9] 这里的做法是为了避免在依赖库情况复杂的情况下过度链接,例如某些 GNOME 程序。这样做对这里的简单例子来说并不是必要的,但应当是无害的。