第 5 章 简单打包

目录

5.1. Packaging tarball
5.2. 大致流程
5.3. 什么是 debmake?
5.4. 什么是 debuild?
5.5. 第一步:获取上游源代码
5.6. Step 2: Generate template files with debmake
5.7. 第三步:编辑模板文件
5.8. Step 4: Building package with debuild
5.9. Step 3 (alternatives): Modification to the upstream source
5.10. Patch by diff -u approach
5.11. Patch by dquilt approach
5.12. Patch by dpkg-source --auto-commit approach

There is an old Latin saying: Longum iter est per praecepta, breve et efficax per exempla (It’s a long way by the rules, but short and efficient with examples).

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

Let’s assume this upstream tarball to be debhello-0.0.tar.xz.

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

Basics for the install from the upstream tarball. 

[base_dir] $ tar --xz -xmf debhello-0.0.tar.xz
[base_dir] $ cd debhello-0.0
[debhello-0.0] $ make
[debhello-0.0] $ make install

Debian packaging requires changing this make install process to install files to the target system image location instead of the normal location under /usr/local.

[注意]注意

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

The big picture for building a single non-native Debian package from the upstream tarball debhello-0.0.tar.xz can be summarized as:

  • The maintainer obtains the upstream tarball debhello-0.0.tar.xz and untars its contents to the debhello-0.0 directory.
  • debmake 命令对上游源码树进行 debian 化(debianize),具体来说,是创建一个 debian 目录并仅向该目录中添加各类模板文件。

    • The debhello_0.0.orig.tar.xz symlink is created pointing to the debhello-0.0.tar.xz file.
    • 维护者须自行编辑修改模板文件。
  • debuild 命令基于已 debian 化的源码树构建二进制软件包。

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

软件包构建的大致流程. 

[base_dir] $ tar --xz -xmf debhello-0.0.tar.xz
[base_dir] $ cd debhello-0.0
[debhello-0.0] $ debmake
[base_dir] $ cd debhello-0.0
[debhello-0.0] $ debmake -x1
I: debmake (version: 5.1.0)
I: Copyright © 2014-2026 Osamu Aoki <[email protected]>
I: [debhello-0.0] $ cd ..
I: Non-native Debian package pkg="debhello", ver="0.0", rev="1" method="dir_d...
I: already in the package-version form: "debhello-0.0"
I: [base_dir] $ ln -sf debhello-0.0.tar.xz debhello_0.0.orig.tar.xz
I: [base_dir] $ cd debhello-0.0
I: parsing option -b ""
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: build_type = make
I: ext_type = c                       1 files
I: ext_type = md                      1 files
I: creating debian/* files with "-x 1" option
I: [debhello-0.0] $ licensecheck --recursive --copyright --deb-machine  . > d...
I: creating debian/copyright by licensecheck.
I: creating debian/control from control.py
I: creating debian/control by control.py
I: creating debian/changelog from extra0_changelog
I: creating debian/rules from extra0_rules
I: creating debian/source/format from extra0source_format
I: creating debian/README.Debian from extra1_README.Debian
I: creating debian/README.source from extra1_README.source
I: creating debian/clean from extra1_clean
I: creating debian/dirs from extra1_dirs
I: creating debian/docs from extra1_docs
I: creating debian/examples from extra1_examples
I: creating debian/gbp.conf from extra1_gbp.conf
I: creating debian/links from extra1_links
I: creating debian/manpages from extra1_manpages
I: creating debian/salsa-ci.yml from extra1_salsa-ci.yml
I: creating debian/watch from extra1nn_watch
I: creating debian/tests/control from extra1tests_control
I: creating debian/upstream/metadata from extra1upstream_metadata
I: creating debian/patches/series from extra1patches_series
I: creating debian/install from extra1bin_install
I: [debhello-0.0] $ wrap-and-sort -ast
I: debian/* may have a blank line at the top.

   ...
[base_dir] $ cd debhello-0.0
[debhello-0.0] $ ... manual customization
[debhello-0.0] $ debuild
   ...

[提示]提示

The debuild command in this and following examples may be substituted by equivalent commands such as the sbuild command.

[提示]提示

If the upstream tarball in the .tar.xz format is available, use it instead of the one in the .tar.xz and .tar.bz2 formats. The xz compression format offers the better compression than the gzip and bzip2 compressions.

[注意]注意

Actual packaging activities are often performed manually without using debmake while referencing only existing similar packages and Debian Policy Manual.

The debmake command is the helper script for the Debian packaging. (第 15 章 debmake(1) 手册页”)

  • It creates good template files for the Debian packages.
  • 它总是将大多数选项的状态与参数设置为合理的默认值。
  • 它能产生上游源码包,并按需创建所需的符号链接。
  • 它不会覆写 debian/ 目录下已存在的配置文件。
  • 它支持多架构(multiarch)软件包。
  • It provides short extracted license texts as debian/copyright using licensecheck to help license review.

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

In retrospective, I created debmake to simplify this documentation. I consider debmake to be more-or-less a demonstration session generator for tutorial purpose.

The debmake command isn’t the only helper script to make a Debian package. If you are interested alternative packaging helper tools, please see:

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

[注意]注意

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

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

Download debhello-0.0.tar.xz

[base_dir] $ wget http://www.example.org/download/debhello-0.0.tar.xz
 ...
[base_dir] $ tar --xz -xmf debhello-0.0.tar.xz
[base_dir] $ tree
.
├── debhello-0.0
│   ├── Makefile
│   ├── README.md
│   └── src
│       └── hello.c
└── debhello-0.0.tar.xz

3 directories, 4 files

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

hello.c

[base_dir] $ cat debhello-0.0/src/hello.c
#include <stdio.h>
int
main()
{
        printf("Hello, world!\n");
        return 0;
}

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

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

Makefile

[base_dir] $ cat debhello-0.0/Makefile
prefix = /usr/local

all: src/hello

src/hello: src/hello.c
        @echo "CFLAGS=$(CFLAGS)" | \
                fold -s -w 70 | \
                sed -e 's/^/# /'
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDCFLAGS) -o $@ $^

install: src/hello
        install -D src/hello \
                $(DESTDIR)$(prefix)/bin/hello

clean:
        -rm -f src/hello

distclean: clean

uninstall:
        -rm -f $(DESTDIR)$(prefix)/bin/hello

.PHONY: all install clean distclean uninstall

[注意]注意

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

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

The output from the debmake command. 

[base_dir] $ cd debhello-0.0
[debhello-0.0] $ debmake -x1
I: debmake (version: 5.1.0)
I: Copyright © 2014-2026 Osamu Aoki <[email protected]>
I: [debhello-0.0] $ cd ..
I: Non-native Debian package pkg="debhello", ver="0.0", rev="1" method="dir_d...
I: already in the package-version form: "debhello-0.0"
I: [base_dir] $ ln -sf debhello-0.0.tar.xz debhello_0.0.orig.tar.xz
I: [base_dir] $ cd debhello-0.0
I: parsing option -b ""
I: binary package=debhello Type=bin / Arch=any M-A=foreign
I: build_type = make
I: ext_type = c                       1 files
I: ext_type = md                      1 files
I: creating debian/* files with "-x 1" option
I: [debhello-0.0] $ licensecheck --recursive --copyright --deb-machine  . > d...
I: creating debian/copyright by licensecheck.
I: creating debian/control from control.py
I: creating debian/control by control.py
I: creating debian/changelog from extra0_changelog
I: creating debian/rules from extra0_rules
I: creating debian/source/format from extra0source_format
I: creating debian/README.Debian from extra1_README.Debian
I: creating debian/README.source from extra1_README.source
I: creating debian/clean from extra1_clean
I: creating debian/dirs from extra1_dirs
I: creating debian/docs from extra1_docs
I: creating debian/examples from extra1_examples
I: creating debian/gbp.conf from extra1_gbp.conf
I: creating debian/links from extra1_links
I: creating debian/manpages from extra1_manpages
I: creating debian/salsa-ci.yml from extra1_salsa-ci.yml
I: creating debian/watch from extra1nn_watch
I: creating debian/tests/control from extra1tests_control
I: creating debian/upstream/metadata from extra1upstream_metadata
I: creating debian/patches/series from extra1patches_series
I: creating debian/install from extra1bin_install
I: [debhello-0.0] $ wrap-and-sort -ast
I: debian/* may have a blank line at the top.

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

  • 源码包名称:debhello
  • 上游版本:0.0
  • 二进制软件包名称:debhello
  • Debian 修订版本:1
  • 软件包类型: bin(ELF 二进制可执行程序软件包)
  • The -x option: -x1 (without maintainer script supports for simplicity)
[注意]注意

Here, the debmake command is invoked with the -x1 option to keep this tutorial simple. Use of default -x2 or more extensive -x3 option is highly recommended.

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

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

[debhello-0.0] $ cd ..
[base_dir] $ tree
.
├── debhello-0.0
│   ├── Makefile
│   ├── README.md
│   ├── debian
│   │   ├── README.Debian
│   │   ├── README.source
│   │   ├── changelog
│   │   ├── clean
│   │   ├── control
│   │   ├── copyright
│   │   ├── dirs
│   │   ├── docs
│   │   ├── examples
│   │   ├── gbp.conf
│   │   ├── install
│   │   ├── links
│   │   ├── manpages
│   │   ├── patches
│   │   │   └── series
│   │   ├── rules
│   │   ├── salsa-ci.yml
│   │   ├── source
│   │   │   └── format
│   │   ├── tests
│   │   │   └── control
│   │   ├── upstream
│   │   │   └── metadata
│   │   └── watch
│   └── src
│       └── hello.c
├── debhello-0.0.tar.xz
└── debhello_0.0.orig.tar.xz -> debhello-0.0.tar.xz

8 directories, 25 files

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

debian/rules(模板文件):. 

[base_dir] $ cd debhello-0.0
[debhello-0.0] $ cat debian/rules
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
# See debhelper(7) (un-comment to enable)
# This is an autogenerated template for debian/rules.
#
# Output every command that modifies files on the build system.
#export DH_VERBOSE = 1
#
# Copy some variable definitions from pkg-info.mk and vendor.mk
# under /usr/share/dpkg/ to here if they are useful.
#
# See FEATURE AREAS/ENVIRONMENT in dpkg-buildflags(1)
# Apply all hardening options
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# Package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
# Package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1
#
# With debhelper version 9 or newer, the dh command exports
# all buildflags.  So there is no need to include the
# /usr/share/dpkg/buildflags.mk file here if compat is 9 or newer.
#
# These are rarely used code. (START)
#
# The following include for *.mk magically sets miscellaneous
# variables while honoring existing values of pertinent
# environment variables:
#
# Architecture-related variables such as DEB_TARGET_MULTIARCH:
#include /usr/share/dpkg/architecture.mk
# Vendor-related variables such as DEB_VENDOR:
#include /usr/share/dpkg/vendor.mk
# Package-related variables such as DEB_DISTRIBUTION
#include /usr/share/dpkg/pkg-info.mk
#
# You may alternatively set them susing a simple script such as:
# DEB_VENDOR ?= $(shell dpkg-vendor --query  Vendor)
#
# These are rarely used code. (END)
#

### main packaging script based on post dh7 syntax
%:
        dh $@

# debmake generated override targets
# Use "make prefix=/usr" (override prefix=/usr/local in Makefile)
#override_dh_auto_install:
#       dh_auto_install -- prefix=/usr

# Do not install python .pyc .pyo if they exist
#override_dh_install:
#       dh_install --list-missing -X.pyc -X.pyo

# Multiarch package requires library files to be installed to
# /usr/lib/<triplet>/ .  If the build system does not support
# $(DEB_HOST_MULTIARCH), you may need to override some targets such as
# dh_auto_configure or dh_auto_install to use $(DEB_HOST_MULTIARCH) .

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

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

debian/control(模板文件):. 

[debhello-0.0] $ cat debian/control
Source: debhello
Section: unknown
Priority: optional
Maintainer: "Osamu Aoki" <[email protected]>
Build-Depends:
 debhelper-compat (= 13),
Standards-Version: 4.7.3
Homepage: <insert the upstream URL, if relevant>
Rules-Requires-Root: no
#Vcs-Git: https://salsa.debian.org/debian/debhello.git
#Vcs-Browser: https://salsa.debian.org/debian/<project_site>

Package: debhello
Section: unknown
Architecture: any
Multi-Arch: foreign
Depends:
 ${misc:Depends},
 ${shlibs:Depends},
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.
 .
 ===== This comes from the unmodified template file =====
 .
 Please edit this template file (debian/control) and other package files
 (debian/*) to make them meet all the requirements of the Debian Policy
 before uploading this package to the Debian archive.
 .
 See
  * https://www.debian.org/doc/manuals/developers-reference/best-pkging-pract...
  * https://www.debian.org/doc/manuals/debmake-doc/ch05.en.html#control
 .
 The synopsis description at the top should be about 60 characters and
 written as a phrase.  No extra capital letters or a final period.  No
 articles — "a", "an", or "the".
 .
 The package description for general-purpose applications should be
 written for a less technical user.  This means that we should avoid
 jargon.  GNOME or KDE is fine but GTK+ is probably not.
 .
 Use the canonical forms of words:
  * Use X Window System, X11, or X; not X Windows, X-Windows, or X Window.
  * Use GTK+, not GTK or gtk.
  * Use GNOME, not Gnome.
  * Use PostScript, not Postscript or postscript.

[警告]警告

If you leave Section: unknown in the template debian/control file unchanged, the lintian error may cause the build to fail.

Since this is the ELF binary executable package, the debmake command sets Architecture: any and Multi-Arch: foreign. Also, it sets required substvar parameters as Depends: ${shlibs:Depends}, ${misc:Depends}. These are explained in 第 6 章 打包工作的基础.

[注意]注意

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.

The debian/copyright file provides the copyright summary data of the Debian package using the licensecheck command.

debian/copyright(模板文件):. 

[debhello-0.0] $ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: FIXME
Upstream-Contact: FIXME
Source: FIXME
Disclaimer: Autogenerated by licensecheck

Files: ./Makefile
 ./README.md
 ./src/hello.c
Copyright: NONE
License: UNKNOWN
 FIXME

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

In order to install files as a part of the system files, the $(prefix) value of /usr/local in the Makefile should be overridden to be /usr. This can be accommodated by the following the debian/rules file with the override_dh_auto_install target setting prefix=/usr.

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

[base_dir] $ cd debhello-0.0
[debhello-0.0] $ vim debian/rules
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@

override_dh_auto_install:
        dh_auto_install -- prefix=/usr

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

Exporting DEB_BUILD_MAINT_OPTION as above sets the hardening options as described in the FEATURE AREAS/ENVIRONMENT in dpkg-buildflags(1). [9]

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

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

The dh_auto_install command for the Makefile based build system essentially runs $(MAKE) install DESTDIR=debian/debhello. The creation of this override_dh_auto_install target changes its behavior to $(MAKE) install DESTDIR=debian/debhello prefix=/usr.

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

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

[debhello-0.0] $ vim debian/control
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/control
Source: debhello
Section: devel
Priority: optional
Maintainer: Osamu Aoki <[email protected]>
Build-Depends:
 debhelper-compat (= 13),
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/debian/debmake-doc
Rules-Requires-Root: no

Package: debhello
Architecture: any
Multi-Arch: foreign
Depends:
 ${misc:Depends},
 ${shlibs:Depends},
Description: Simple packaging example for debmake
 This Debian binary package is an example package.
 (This is an example only)

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

[debhello-0.0] $ vim debian/copyright
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: debhello
Upstream-Contact: Osamu Aoki <[email protected]>
Source: https://salsa.debian.org/debian/debmake-doc

Files:     *
Copyright: 2015-2021 Osamu Aoki <[email protected]>
License:   Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Let’s remove unused template files and edit remaining template files:

  • debian/README.source
  • debian/patches/series (No upstream patch)
  • clean
  • dirs
  • install
  • links

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

[debhello-0.0] $ rm -f debian/clean debian/dirs debian/install debian/links
[debhello-0.0] $ rm -f debian/README.source debian/source/*.ex
[debhello-0.0] $ rm -rf debian/patches
[debhello-0.0] $ tree -F debian
debian/
├── README.Debian
├── changelog
├── control
├── copyright
├── docs
├── examples
├── gbp.conf
├── manpages
├── rules*
├── salsa-ci.yml
├── source/
│   └── format
├── tests/
│   └── control
├── upstream/
│   └── metadata
└── watch

4 directories, 14 files

[提示]提示

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

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

Building package with debuild

[base_dir] $ cd debhello-0.0
[debhello-0.0] $ debuild
 dpkg-buildpackage -us -uc -ui -i
dpkg-buildpackage: info: source package debhello
dpkg-buildpackage: info: source version 0.0-1
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Osamu Aoki <[email protected]>
 dpkg-source -i --before-build .
dpkg-buildpackage: info: host architecture amd64
 debian/rules clean
dh clean
   dh_auto_clean
        make -j12 distclean
 ...
 debian/rules binary
dh binary
   dh_update_autotools_config
   dh_autoreconf
   dh_auto_configure
   dh_auto_build
        make -j12 INSTALL="install --strip-program=true"
make[1]: Entering directory '/path/to/base_dir/debhello-0.0'
# CFLAGS=-g -O2 -Werror=implicit-function-declaration
 ...
Finished running lintian.

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

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

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

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

[debhello-0.0] $ cd ..
[base_dir] $ tree -FL 1
./
├── debhello-0.0/
├── debhello-0.0.tar.xz
├── debhello-dbgsym_0.0-1_amd64.deb
├── debhello_0.0-1.debian.tar.xz
├── debhello_0.0-1.dsc
├── debhello_0.0-1_amd64.build
├── debhello_0.0-1_amd64.buildinfo
├── debhello_0.0-1_amd64.changes
├── debhello_0.0-1_amd64.deb
└── debhello_0.0.orig.tar.xz -> debhello-0.0.tar.xz

2 directories, 9 files

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

  • The debhello_0.0.orig.tar.xz is a symlink to the upstream tarball.
  • 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 的调试符号二进制软件包。另请参见 第 10.21 节 “-dbgsym package”
  • 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 的内容:. 

[base_dir] $ tar --xz -tf debhello-0.0.tar.xz
debhello-0.0/
debhello-0.0/src/
debhello-0.0/src/hello.c
debhello-0.0/Makefile
debhello-0.0/README.md
[base_dir] $ tar --xz -tf debhello_0.0-1.debian.tar.xz
debian/
debian/README.Debian
debian/changelog
debian/control
debian/copyright
debian/docs
debian/examples
debian/gbp.conf
debian/manpages
debian/rules
debian/salsa-ci.yml
debian/source/
debian/source/format
debian/tests/
debian/tests/control
debian/upstream/
debian/upstream/metadata
debian/watch

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

The debhello-dbgsym_0.0-1_amd64.deb contains the debug symbol files to be installed to the target system.

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

[base_dir] $ dpkg -c debhello-dbgsym_0.0-1_amd64.deb
drwxr-xr-x root/root ...  ./
drwxr-xr-x root/root ...  ./usr/
drwxr-xr-x root/root ...  ./usr/lib/
drwxr-xr-x root/root ...  ./usr/lib/debug/
drwxr-xr-x root/root ...  ./usr/lib/debug/.build-id/
drwxr-xr-x root/root ...  ./usr/lib/debug/.build-id/00/
-rw-r--r-- root/root ...  ./usr/lib/debug/.build-id/00/d21e230186d135c41c9540...
drwxr-xr-x root/root ...  ./usr/share/
drwxr-xr-x root/root ...  ./usr/share/doc/
lrwxrwxrwx root/root ...  ./usr/share/doc/debhello-dbgsym -> debhello
[base_dir] $ dpkg -c debhello_0.0-1_amd64.deb
drwxr-xr-x root/root ...  ./
drwxr-xr-x root/root ...  ./usr/
drwxr-xr-x root/root ...  ./usr/bin/
-rwxr-xr-x root/root ...  ./usr/bin/hello
drwxr-xr-x root/root ...  ./usr/share/
drwxr-xr-x root/root ...  ./usr/share/doc/
drwxr-xr-x root/root ...  ./usr/share/doc/debhello/
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/README.Debian
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/changelog.Debian.gz
-rw-r--r-- root/root ...  ./usr/share/doc/debhello/copyright

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

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

[debhello-0.0] $ dpkg -f debhello-dbgsym_0.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: debhello (= 0.0-1)
[debhello-0.0] $ dpkg -f debhello_0.0-1_amd64.deb pre-depends \
            depends recommends conflicts breaks
Depends: libc6 (>= 2.34)

[小心]小心

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

[注意]注意

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

The above example did not touch the upstream source to make the proper Debian package. An alternative approach as the maintainer is to modify files in the upstream source. For example, Makefile may be modified to set the $(prefix) value to /usr.

[注意]注意

The above 第 5.7 节 “第三步:编辑模板文件” using the debian/rules file is the better approach for packaging for this example. But let’s continue on with this alternative approaches as a leaning experience.

In the following, let’s consider 3 simple variants of this alternative approach to generate debian/patches/* files representing modifications to the upstream source in the Debian source format 3.0 (quilt). These substitute 第 5.7 节 “第三步:编辑模板文件”” in the above step-by-step example:

Please note the debian/rules file used for these examples doesn’t have the override_dh_auto_install target as follows:

debian/rules(备选的维护者版本):. 

[base_dir] $ cd debhello-0.0
[debhello-0.0] $ vim debian/rules
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/rules
#!/usr/bin/make -f
export DH_VERBOSE = 1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

%:
        dh $@

Here, the patch file 000-prefix-usr.patch is created using the diff command.

Patch by diff -u

[base_dir] $ cp -a debhello-0.0 debhello-0.0.orig
[debhello-0.0] $ vim debhello-0.0/Makefile
 ... hack, hack, hack, ...
[base_dir] $ diff -Nru debhello-0.0.orig debhello-0.0 >000-prefix-usr.patch
[base_dir] $ cat 000-prefix-usr.patch
diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile
--- debhello-0.0.orig/Makefile  2026-01-30 14:31:05.338972920 +0000
+++ debhello-0.0/Makefile       2026-01-30 14:31:05.420927855 +0000
@@ -1,4 +1,4 @@
-prefix = /usr/local
+prefix = /usr

 all: src/hello

[base_dir] $ rm -rf debhello-0.0
[base_dir] $ mv -f debhello-0.0.orig debhello-0.0

Please note that the upstream source tree is restored to the original state after generating a patch file 000-prefix-usr.patch.

This 000-prefix-usr.patch is edited to be DEP-3 conforming and moved to the right location as below.

000-prefix-usr.patch (DEP-3): 

[debhello-0.0] $ echo '000-prefix-usr.patch' >debian/patches/series
[debhello-0.0] $ vim ../000-prefix-usr.patch
 ... hack, hack, hack, ...
[debhello-0.0] $ mv -f ../000-prefix-usr.patch debian/patches/000-prefix-usr....
[debhello-0.0] $ cat debian/patches/000-prefix-usr.patch
From: Osamu Aoki <[email protected]>
Description: set prefix=/usr patch
diff -Nru debhello-0.0.orig/Makefile debhello-0.0/Makefile
--- debhello-0.0.orig/Makefile
+++ debhello-0.0/Makefile
@@ -1,4 +1,4 @@
-prefix = /usr/local
+prefix = /usr

 all: src/hello

[注意]注意

When generating the Debian source package by dpkg-source via dpkg-buildpackage in the following step of 第 5.8 节 “Step 4: Building package with debuild, the dpkg-source command assumes that no patch was applied to the upstream source, since the .pc/applied-patches is missing.

Here, the patch file 000-prefix-usr.patch is created using the dquilt command.

dquilt is a simple wrapper of the quilt program. The syntax and function of the dquilt command is the same as the quilt(1) command, except for the fact that the generated patch is stored in the debian/patches/ directory.

Patch by dquilt

[debhello-0.0] $ dquilt new 000-prefix-usr.patch
Patch debian/patches/000-prefix-usr.patch is now on top
[debhello-0.0] $ dquilt add Makefile
File Makefile added to patch debian/patches/000-prefix-usr.patch
 ... hack, hack, hack, ...
[debhello-0.0] $ head -1 Makefile
prefix = /usr
[debhello-0.0] $ dquilt refresh
Refreshed patch debian/patches/000-prefix-usr.patch
[debhello-0.0] $ dquilt header -e --dep3
 ... edit the DEP-3 patch header with editor
[debhello-0.0] $ tree -a
.
├── .pc
│   ├── .quilt_patches
│   ├── .quilt_series
│   ├── .version
│   ├── 000-prefix-usr.patch
│   │   ├── .timestamp
│   │   └── Makefile
│   └── applied-patches
├── Makefile
├── README.md
├── debian
│   ├── README.Debian
│   ├── README.source
│   ├── changelog
│   ├── clean
│   ├── control
│   ├── copyright
│   ├── dirs
│   ├── docs
│   ├── examples
│   ├── gbp.conf
│   ├── install
│   ├── links
│   ├── manpages
│   ├── patches
│   │   ├── 000-prefix-usr.patch
│   │   └── series
│   ├── rules
│   ├── salsa-ci.yml
│   ├── source
│   │   └── format
│   ├── tests
│   │   └── control
│   ├── upstream
│   │   └── metadata
│   └── watch
└── src
    └── hello.c

9 directories, 30 files
[debhello-0.0] $ cat debian/patches/series
000-prefix-usr.patch
[debhello-0.0] $ cat debian/patches/000-prefix-usr.patch
Description: set prefix=/usr patch
Author: Osamu Aoki <[email protected]>
Index: debhello-0.0/Makefile
===================================================================
--- debhello-0.0.orig/Makefile
+++ debhello-0.0/Makefile
@@ -1,4 +1,4 @@
-prefix = /usr/local
+prefix = /usr

 all: src/hello

Here, Makefile in the upstream source tree doesn’t need to be restored to the original state for the packaging.

[注意]注意

When generating the Debian source package by dpkg-source via dpkg-buildpackage in the following step of 第 5.8 节 “Step 4: Building package with debuild, the dpkg-source command assumes that patches were applied to the upstream source, since the .pc/applied-patches exists.

The upstream source tree can be restored to the original state for the packaging.

The upstream source tree (restored): 

[debhello-0.0] $ dquilt pop -a
Removing patch debian/patches/000-prefix-usr.patch
Restoring Makefile

No patches applied
[debhello-0.0] $ head -1 Makefile
prefix = /usr/local
[debhello-0.0] $ tree -a .pc
.pc
├── .quilt_patches
├── .quilt_series
└── .version

1 directory, 3 files

Here, Makefile is restored and the .pc/applied-patches is missing.

Here, the patch file isn’t created in this step but the source files are setup to create debian/patches/* files in the following step of 第 5.8 节 “Step 4: Building package with debuild”.

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

Modified Makefile

[debhello-0.0] $ vim Makefile
 ... hack, hack, hack, ...
[debhello-0.0] $ head -n1 Makefile
prefix = /usr

Let’s edit debian/source/local-options:

debian/source/local-options for auto-commit

[debhello-0.0] $ mv debian/source/local-options.ex debian/source/local-option...
[debhello-0.0] $ vim debian/source/local-options
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/source/local-options
# == Patch applied strategy (merge) ==
#
# The source outside of debian/ directory is modified by maintainer and
# different from the upstream one:
#   * Workflow using dpkg-source commit (commit all to VCS after dpkg-source ...
#       https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html#dpkg-sour...
#   * Workflow described in dgit-maint-merge(7)
#
single-debian-patch
auto-commit

Let’s edit debian/source/local-patch-header:

debian/source/local-patch-header for auto-commit

[debhello-0.0] $ mv debian/source/local-patch-header.ex debian/source/local-p...
[debhello-0.0] $ vim debian/source/local-patch-header
 ... hack, hack, hack, ...
[debhello-0.0] $ cat debian/source/local-patch-header
Description: debian-changes
Author: Osamu Aoki <[email protected]>

Let’s remove debian/patches/* files and other unused template files.

移除未使用的模板文件. 

[debhello-0.0] $ rm -f debian/clean debian/dirs debian/install debian/links
[debhello-0.0] $ rm -f debian/README.source debian/source/*.ex
[debhello-0.0] $ rm -rf debian/patches
[debhello-0.0] $ tree debian
debian
├── README.Debian
├── changelog
├── control
├── copyright
├── docs
├── examples
├── gbp.conf
├── manpages
├── rules
├── salsa-ci.yml
├── source
│   ├── format
│   ├── local-options
│   └── local-patch-header
├── tests
│   └── control
├── upstream
│   └── metadata
└── watch

4 directories, 16 files

There are no debian/patches/* files at the end of this step.

[注意]注意

When generating the Debian source package by dpkg-source via dpkg-buildpackage in the following step of 第 5.8 节 “Step 4: Building package with debuild, the dpkg-source command uses options specified in debian/source/local-options to auto-commit modification applied to the upstream source as patches/debian-changes.

Let’s inspect the Debian source package generated after the following 第 5.8 节 “Step 4: Building package with debuild step and extracting files from debhello-0.0.debian.tar.xz.

Inspect debhello-0.0.debian.tar.xz after debuild

[base_dir] $ tar --xz -xvf debhello_0.0-1.debian.tar.xz
debian/
debian/README.Debian
debian/changelog
debian/control
debian/copyright
debian/docs
debian/examples
debian/gbp.conf
debian/manpages
debian/patches/
debian/patches/debian-changes
debian/patches/series
debian/rules
debian/salsa-ci.yml
debian/source/
debian/source/format
debian/tests/
debian/tests/control
debian/upstream/
debian/upstream/metadata
debian/watch

Let’s check generated debian/patches/* files.

Inspect debian/patches/* after debuild

[base_dir] $ cat debian/patches/series
debian-changes
[base_dir] $ cat debian/patches/debian-changes
Description: debian-changes
Author: Osamu Aoki <[email protected]>

--- debhello-0.0.orig/Makefile
+++ debhello-0.0/Makefile
@@ -1,4 +1,4 @@
-prefix = /usr/local
+prefix = /usr

 all: src/hello

The Debian source package debhello-0.0.debian.tar.xz is confirmed to be generated properly with debian/patches/* files for the Debian modification.



[9] This is a cliché to force a read-only relocation link for the hardening and to prevent the lintian warning W: debhello: hardening-no-relro usr/bin/hello. This is not really needed for this example but should be harmless. The lintian tool seems to produce a false positive warning for this case which has no linked library.

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