本文发布于Cylon的收藏册,转载请著名原文链接~

deb 概述

deb包(.deb)是 Debian 和基于 Debian衍生操作系统(如Ubuntu)中使用的一种软件包的格式。deb是一种基于 Unix ar [3] (Unix archiver) 的归档文件。其中包含二进制文件、配置文件和其他软件所需的资源。deb包可用于安装、升级和卸载软件包。通常,Debian操作系统的用户使用apt(Advanced Package Tool)等软件包管理器工具来管理deb包。通过这些工具,用户可以轻松下载、安装和管理软件包,而无需手动编译、安装和解决软件包之间的依赖关系。

deb VS rpm

  • 包的归档格式不同:deb是基于 ar 的归档模式,而RPM是基于 cpio 的归档模式
  • 包的结构不同:deb包要求必须包含一个 DEBIAN 目录;而RPM不需要以来额外的目录结构
  • 包的依赖机制不同:
    1. Deb使用epoch,而RPM使用build number:在Deb中,epoch是一个可选的字段,它允许呈现基准日期之前的先前版本。而在RPM中,build number表示软件包编译的次数。因此,在Deb中,为了解决版本控制问题,epoch是非常重要的,而在RPM中,则更关注build number。
    2. Deb使用逆向依赖关系,而RPM使用依赖关系:在Deb中,依赖项是从包本身向外扩展,在解决依赖问题时可以通过逆向依赖关系进行。而在RPM中,则更喜欢使用依赖关系直接指向其他包。
    3. Deb允许代理软件包,而RPM则不允许代理软件包:Deb中,软件包可以使用另一种软件包的代理来提供功能。在RPM中,软件包需要直接引用相关的软件包。这意味着在Deb中,对于版本控制,可以用另一种代理软件包来解决问题,而在RPM中必须直接引用包。
    4. Deb允许多重依赖关系,RPM则不允许:Deb允许使用多个依赖项列表,以便包与不同版本的库兼容。在RPM中,需要在每个包中定义依赖项和其版本,不能使用多重依赖。

deb包的分析

deb包的结构

deb 最重要的是 控制文件 Control ,该文件记录了deb包与其安装的程序的信息。

在deb包内部包含一组模拟 Linux 文件系统的文件夹,例如 /usr, /usr/bin, /opt等等。 放置在其中一个目录中的文件将在安装期间复制到实际文件系统中的相同位置。 因此,例如将二进制文件放入 <.deb>/usr/local/bin/binaryfile 将被安装到 /usr/local/bin/binaryfile.

对于deb 包的命名是遵循着一个特定的格式:

1
<name>_<version>-<revision>_<architecture>.deb
  • <name> 构建的deb包名称,如nginx
  • <version> 程序的版本号 ,如1.20
  • <revision> 当前 deb 包的版本号
  • <architecture> 表示构建出的包的操作系统架构,如,amd64、i386

如果你构建一个nginx-1.20的arm操作系统下的,那么deb包名格式则为 nginx_1.20-1_arm64.deb

control文件 [2]

Deb软件包(.deb文件)中的 控制文件 (control) 包含有关软件包的 源码元数据二进制元数据 ,用于描述例如软件包的名称、版本、描述、作者、许可证和依赖关系等信息。在创建和打包Deb软件包时,必须创建和编辑control文件以包含关于软件包的所有必要信息。

控制文件 (control) 由一个或多节组成,各节之间用空行分隔。解析器可以接受仅由空格和制表符组成的行作为节分隔符,但控制文件应该使用空行。一些控制文件只允许一个节;其他人允许多个,在这种情况下,每个节通常指的是不同的包,控制文件中节的顺序很重要。

而 Control 文件存在两种,一种为 源代码包控制文件 (Source package control files),这种类型的控制文件主要用于定义源代码在构建时的一些元数据信息,例如需要构建一个nginx.deb,那么源代码控制文件就是用于描述下载下来的源代码相关的数据,这种文件被放置在目录 debian/control

另一种为二进制包控制文件 (Binary package control files),这部分是控制在nginx编译后制作成deb包的控制文件,这种控制文件被放置在 DEBIAN/control

另外还存在一种 源代码控制文件 ( Debian source control files ) ,包含完整的源代码和软件包元数据信息。它们通常存储在软件包的源代码存储库中,供开发人员和维护人员使用。包含在源代码控制文件中的信息包括软件包名称、版本、维护人员、许可证、依赖关系、构建和安装指令集等。

例如下面为 control 文件常见的字段类型:

字段 说明
Package <软件包的名称>
Priority <软件包的优先级>
Section <软件包的分类>
Version <软件包的版本>
Depends <软件包的依赖关系>
Architecture <软件包的体系结构>
Maintainer <软件包的维护者>
Description <软件包的描述>
Rules-Requires-Root [1] Rules-Requires-Root是Debian软件包中一个可选的控制文件,定义了软件包在安装和运行时是否需要超级用户权限;No/Yes
Standards-Version: deb包 控制文件 中的一个元素,用于指定软件包所遵循的标准和规范的版本号。该字段的值应该是一个数字,例如:“3.9.8”, “2.3.0.0”

其中,上面给出的通常是必须指定的字段,如一个control 文件必须包含 PackagePrioritySectionVersionArchitectureMaintainerDescription 。由于等 deb软件包通常都安装在系统上,在 control 文件中指定软件包的依赖关系非常重要。这可通过Depends字段完成。

例如下面是一个 control 文件的示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 源代码控制文件
Source: nginx
Maintainer: root <root@debian-template>
Section: comm
Priority: optional
Homepage: https://nginx.org

# 二进制控制文件
Package: nginx
Version: 1.22.1
Architecture: amd64
Standards-Version: 1.0.0
Build-Depends: debhelper-compat (= 13)
Description: Nginx HTTP server Nginx ("engine x") is a web server created by Igor Sysoev. It is known for its high performance, stability, and low resource consumption.

rules文件 [5]

rules文件的规范

rules文件在deb中被成为 主要构建脚本 (Main building script),这个文件必须是一个可执行的Makefile。它包含了特定于包的源代码(如果需要)和构建一个或多个二进制包的指令。

debian/rules文件 必须以 #!/usr/bin/make -f 开头,这个声明是为了通过调用其名称而不是显式调用make来调用它。也就是说,调用 make -f debian/rules args..../debian/rules args... 必须产生相同的行为。

在没有使用其他方法的充分理由的情况下,实现Debian软件包构建过程的推荐方式是使用dh工具。这包括debian/rules构建脚本的内容。dh是Debian中最常见的封装辅助工具。使用它通常可以节省遵守本文档中规则的工作,因为dh将自动实现许多规则而无需明确的指示。

rules 文件内置了一些阶段,这标志着整个源码包构建的过程;如 debian/rules 必须由:clean、binary、binary-arch、binary-indep、build、build-arch 和 build-indep,如果通过 dpkg-buildpackage 构建时,这些阶段则是调用的阶段。

需要注意的一点是,由于交互式 debian/rules 脚本无法自动编译该软件包,也使其他人难以复制相同的二进制软件包,因此所有必需的阶段都必须是非交互式的。它还遵循这些阶段所依赖的任何阶段也必须是非交互式的。

rules文件的构建过程

通俗来说,rules文件是一个将源码包转换为二进制包的一个构建模式,首先,binarey二进制包写入解压后的源码包的父目录。其次,所需的目标可以写入 /tmp、/var/tmp 和 TMPDIR 环境变量指定的目录,但不得依赖于其中任何一个的内容。

这个限制旨在防止源代码包构建创建和依赖于其外部状态,从而影响多个独立的重建过程。特别地,所需的目标不能尝试写入 HOME 目录。

rules文件的过程,也是阶段:

  • build (required):该阶段应该执行软件包的所有配置和编译操作,例如 make,这个阶段执行前,会先运行 clean 阶段
  • build-indepbuild-arch (required)
    • build-arch (required):该阶段必须执行生成所有与架构(architecture)有关的二进制包,例如 make intall 好的 x86 的二进制文件
    • build-indep (required): 该阶段执行生成所有与 架构(architecture)无关的二进制包操作,所需的所有配置和编译操作。build 阶段应该依赖于这些阶段,或者采取与调用这些阶段相同的操作,
    • build-archbuild-indep 不能执行任何可能需要 root 权限的操作。
    • 通俗来讲,这两个阶段会被用于操作构建完的事情,对于rpmbuild,这里操作就是%files的操作了。
  • binary (required), binary-arch (required), binary-indep (required):
    • binary:该阶段必须是用户从此源代码包生成二进制包所需的全部内容。它分为两个部分:binary-arch用于生成特定架构的二进制包,binary-indep用于生成其他类型的二进制包
    • binary-* 阶段都应该依赖于 build 阶段或适当的 build-arch 或 build-indep 阶段,以便在没有构建该软件包时构建它。然后使用 dpkg-gencontrol 创建其控制文件以及dpkg-deb 构建成一个二进制包,并将它们放置在顶级目录的父目录中(即你执行构建的目录的上级),以创建相应的二进制包。
    • binary-archbinary-indep 两个阶段必须要存在。如果其中一个阶段无事可做(如果源代码仅生成单个二进制包,无论是否架构相关,始终是如此),它仍必须存在并始终成功。
    • 根据Rules-Requires-Root字段的值的配置,binary阶段可能需要作为root用户调用。
  • clean (required):该阶段将撤消 buildbinary 阶段可能产生的所有效果,除了它应该保留在上次运行 binary 阶段时在父目录中创建的任何输出文件。
  • patch (optional):此阶段执行所需的任何其他操作,以使源代码包准备好进行编辑(解包其他上游归档文件、应用补丁等)

这些阶段执行构建的工作目录,与deb包的工作目录不同,他的工作目录为当前目录作为包的根目录来使用,有一点需要注意的是,这里的架构的觉得为 dpkg-architecture 命令决定的,在不同架构机器上构建则为不同的架构的包

工作目录

在构建deb软件包(.deb文件)时,通常需要将软件包的文件和目录安排在特定的文件目录中,这个特定目录就是打包时的工作目录,通过上面的解释,已知,deb包分为两种 源代码包二进制包,而两中类型的工作目录不相同。

例如,我们需要构建一个源码软件包,假设为要为一个nginx制作 deb包,那么他的工作目录则为 debian,而control 文件 和 rule 文件则是必须的,封包的内容目录 则为控制文件中 Package 配置的名字,这里配置的为 nginx,那么这个deb包封包时寻找的内容则为 debian/nginx

在例如,我们需要构建一个二进制软件包,那么他的工作目录为 DEBIAN,control文件与 changelog 则是必须的,而封包的内容目录 当前目录,也就是 DEBIAN,制作时的控制文件这些不会被封入包中

那么完整的制作流程为

  • 在源代码目录下创建一个名为nginx的子目录 mkdir debian
  • 在nginx目录下创建名为 DEBIAN 的子目录,包含 control 文件,在DEBIAN目录中包含control文件是必须的,因为它是软件包元数据的中心存储库。
  • 例如我们编译完的内容,nginx 的配置文件在 /etc/下,那么这个 etc 则在 nginx 子目录下
  • 在工作目录下创建 rules 文件,这里面写明了构建的命令,例如:
    • build:这个部分用于执行编译和构建软件的命令。
    • clean:这个部分用于清除编译输出,以便你可以重新构建软件包。
    • install:这个部分指定了如何将软件安装到目标系统中。
    • binary:这个部分用于在 Debian 软件包中打包二进制文件。
  • 其中该结构中还包含一些钩子脚本文件 debian/p* 而这个 p* 文件的命名是固定的。下面是一些常见的 p* 文件名:
    • debian/package.install:定义软件包中需要安装的文件和目录。
    • debian/package.manpages:将软件包中的 man 页面添加到 man 手册中。
    • debian/package.docs:将软件包中的文档添加到系统上的 /usr/share/doc 目录。
    • debian/package.preinst:在软件包安装前执行的脚本。
    • debian/package.postinst:在软件包安装后执行的脚本。
    • debian/package.prerm:在软件包卸载前执行的脚本。
    • debian/package.postrm:在软件包卸载后执行的脚本。

实战:从0构建一个 deb 包

准备条件

上面介绍的为deb包的一些基础,作为实战的一些理论知识,下面将以nginx为代表将其制作为deb包;通过前面知识了解到,deb包分为 源代码包二进制包,那么nginx明显为源代码包,我们就需要按照 源代码包 =》二进制包 这种顺序依次定义,而 debian 提供了一系列的命令可以帮助生成这些文件,我们只需要改写具体的逻辑就可以完成包的制作,如 dh_make , dh_install 等命令。

对于 deb 包的标准,debian 官方有一些列的教程,称为 Debian Policy Manual [4] ,可以通过这个手册,整个deb包中所需的一些理论知识,控制文件,维护脚本,包间的依赖关系,共享库等进行详细的说明

dh工具

dh [6](Debhelper)工具是Debian中自带的一个构建deb包的工具集。dh工具包含了一系列的脚本,用于从打包的源代码中自动化生成debian目录下的文件。这些脚本是 debian/rules 文件中的一部分,它们负责处理诸如构建、安装、打包、删除等任务。

dh工具包括多个命令及其选项,更多的 dh 工具可以参考官方

命令 说明
dh_make 创建一个基本的在deb包打包时的工作框架
dh_auto_configure 自动运行 configure 脚本以生成 Makefile
dh_install 将文件复制到正确的deb包的构建目录中,一些常见选项:
-s--sourcedir=: 指定源代码目录;
-X--exclude: 排除在安装中不必要的文件;
-n--noscripts: 在安装软件包时不运行脚本;
-Z: 表示安装的文件不要在规则中注册;
dh_builddeb .deb 文件格式构建软件包
dh_clean 清理debian目录和生成的文件,以确保它们不会在构建时对结果造成影响。
dh_gencontrol 生产和安装control文件
dh_installsystemd 安装systemd单元文件

dh_make

dh_make 命令是一个用于快速创建 deb 包的命令行工具。它可以根据用户提供的基本信息和软件包源代码自动创建 deb 包的基础结构,包括 debian/ 目录和相关文件,如 controlrules 以及 changelog 等文件。DH 表示 Debian 包含 debhelper 建议的目录和文件结构。

在默认情况下,dh_make 命令是交互式的,它会提示你输入一些必要的软件包信息,如软件包名称、版本号、作者、软件许可证等。如果你想非交互方式运行 dh_make 命令,并指定软件包信息,则可以使用 -s 选项。

1
$ dh_make -s --createorig -f ../{some_package-1.2.3}.tar.gz -p {some_package_1.2.3-1}.deb

在上述命令中,-s 选项表示以非交互方式运行 dh_make 命令,并将软件包的基本信息作为参数指定。--createorig 选项表示我们想要创建一个原始的源代码包,-f 选项指定软件包源代码的文件名和路径,-p 选项指定要创建的 Debian 软件包的名称和版本号。

而上述命令会提示输入一些基本的详细信息,以便在 debian/control 控制文件中为软件包设置元数据。dh_make 会询问输入软件包的名称、版本、描述、组件、维护人员等信息,是否以这些参数作为构建,如果不需要这部确认可以使用 -y 默认同意

下面是通过 dh_make 构建出的在构建deb包的工作目录,这种方式下可以很明了的理解deb包的结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ tree debian/
debian/
├── changelog
├── control
├── copyright
├── manpage.1.ex
├── manpage.sgml.ex
├── manpage.xml.ex
├── nginx.cron.d.ex
├── nginx.doc-base.EX
├── nginx-docs.docs
├── postinst.ex
├── postrm.ex
├── preinst.ex
├── prerm.ex
├── README.Debian
├── README.source
├── rules
├── salsa-ci.yml.ex
├── source
│   └── format
└── watch.ex

到这里,我们就完成了一个源码包的前提条件的构建,只需要稍微修改控制文件即可,进行后续的二进制包的构建。

这里最终的 控制文件 如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 源代码控制文件
Source: nginx
Maintainer: root <root@debian-template>
Section: comm
Priority: optional
Homepage: https://nginx.org

# 二进制控制文件
Package: nginx-d
Version: 1.22.1
Architecture: amd64
Standards-Version: 1.0.0
Build-Depends: debhelper-compat (= 13)
Description: Nginx HTTP server Nginx ("engine x") is a web server created by Igor Sysoev. It is known for its high performance, stability, and low resource consumption.

准备rules文件

通过上面的rules文件部分介绍,了解到 rules 文件就是一个 Makefile,并且包含三个阶段

  • clean – 删除所有build与binary阶段产生的内容

  • build – 编译与构建的步骤

  • binary – binary阶段将创建deb包的root目录,这个目录被包含在 debian 目录下,而目录名则为 control 文件中配置的 Package 名字,即 debian/<source package name>

这些阶段都通过 dpkg-buildpackage 在构建时被执行,一个rules文件的模板如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/make -f

clean:
	@# Do nothing

build:
	@# Do nothing

binary:
	@# Do nothing
	dh_gencontrol
	dh_builddeb

那这个 nginx 的 rules 文件则为下述所示:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/make -f

# 列出您要編譯的檔案和目錄
export DH_VERBOSE=1

PACKAGE=nginx
UPSTREAM_VERSION=1.22.1

# 設置打包的參數
export DEB_BUILD_MAINT_OPTIONS = hardening=+all

export BUILDDIR_WORK = $(CURDIR)/debian/$(PACKAGE)

export BUILDDIR=$(CURDIR)/debian/tmp

# 定義建立目錄,它會在${CURDIR}/debian/$PACKAGE下創建
debian/$PACKAGE::

%:

# build阶段,将完成软件的编译
build: 
	tar zxf nginx-$(UPSTREAM_VERSION).tar.gz
	# 配置 Nginx 以使用必要的模塊和參數
	cd nginx-$(UPSTREAM_VERSION) && \
	    ./configure \
	    --conf-path=/etc/nginx/nginx.conf \
	    --pid-path=/var/run/nginx \
	    --sbin-path=/usr/sbin/nginx \
	    --http-log-path=/var/log/nginx/error.log \
	    --error-log-path=/var/log/nginx/access.log \
	    --http-client-body-temp-path=/etc/nginx/ \
		--http-proxy-temp-path=/var/run/nginx/ \
		--http-fastcgi-temp-path=/var/run/nginx/ \
		--http-uwsgi-temp-path=/var/run/nginx/ \
		--http-scgi-temp-path=/var/run/nginx/ \
		--pid-path=/var/run/nginx/nginx.pid \
        --with-http_ssl_module \
		--without-http_gzip_module 
	
	cd nginx-$(UPSTREAM_VERSION) && make
	# 这里存在一个问题,即 prefix 与 DESTDIR 不要同时写,make install 被安装在哪里
	# 如果配置了prefix 那么则被安装在 prefix/DESTDIR 变成了双重目录
	# 这里不配置 prefix 只配置DESTDIR则会被安装在 deb 包在构建时的工作目录,这里制定了$(BUILDDIR)
	# 将被放置在 $(BUILDDIR)
	cd nginx-$(UPSTREAM_VERSION) && make install DESTDIR=$(BUILDDIR)

	# 清理
	rm -rf nginx-$(UPSTREAM_VERSION)

clean:
	rm -rf nginx-$(UPSTREAM_VERSION)
	rm -rf $(BUILDDIR)
	rm -rf $(BUILDDIR_WORK)

build-indep:
	# 构建前测试目录
	dh_testdir

build-arch:
	dh_testdir

binary-indep:
	dh_testdir
	
	# 测试是否有root权限
	dh_testroot
	
	# 在 binary 阶段中,执行的安装操作,创建 /etc/nginx目录
	# 这些命令执行的是 install -d
	# 为什么使用 dh tool 而不用install,因为dh tool是rules file的一部分,也就是他默认的工作目录是
	# 构建deb包的工作目录,这里必须是相对目录
	# 而对于第一个的 "/" 与 最后一个 "/" 都不要写,会被自动除虫上
	dh_installdirs etc/nginx
	dh_installdirs var/log/nginx
	dh_installdirs var/run/nginx
	dh_install etc/nginx/* etc/nginx
	dh_install usr/sbin/* usr/sbin
	
	# 这里创建了二进制包的目录结构
	install -d $(BUILDDIR_WORK)/DEBIAN
	
	# dh_gencontrol可以根据源码包的配置来生成二进制包的control文件
	# 底层封装的是 dh_gencontrol -O --file --package=nginx 为二进制包生成
	dh_gencontrol -O --file --package=$(PACKAGE)
	
	# dh_installchangelogs 可以根据源码包中的changelog来生成二进制包的changelog
	# changelog 和 control file是二进制包必须的文件
	# dh_gencontrol -O --file --package=nginx
	# 底层执行的为在 deb 包根目录的/usr/share/doc/nginx 中生成changelog
	# dh_installchangelogs
	#    install -d debian/nginx/usr/share/doc/nginx
	#    install -p -m0644 debian/changelog debian/nginx/usr/share/doc/nginx/changelog.Debian
	dh_installchangelogs
	
	# 这里将修复链接路径及压缩,如果你的一些软连接需要修复时可以使用
	dh_compress


binary: binary-indep
	# dh_builddeb命令将会构建一个二进制包
	# dh_builddeb封装的时dpkg-deb命令
	#   dpkg-deb --build debian/nginx ..
	dh_builddeb

.PHONY: clean binary-indep binary-arch binary install build

执行构建

通过执行 dpkg-buildpackage -b 来构建二进制源码包

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	install -d debian/nginx/usr/sbin
	cp --reflink=auto -a debian/tmp/usr/sbin/nginx debian/nginx/usr/sbin/
install -d /root/nginx/debian/nginx/DEBIAN
dh_gencontrol -O --file --package=nginx
	dpkg-gencontrol -pnginx -ldebian/changelog -Tdebian/nginx.substvars -Pdebian/nginx
dpkg-gencontrol: warning: unknown information field 'Version' in input data in package's section of control info file
dpkg-gencontrol: warning: unknown information field 'Standards-Version' in input data in package's section of control info file
	chmod 0644 -- debian/nginx/DEBIAN/control
	chown 0:0 -- debian/nginx/DEBIAN/control
dh_installchangelogs
	install -d debian/nginx/usr/share/doc/nginx
	install -p -m0644 debian/changelog debian/nginx/usr/share/doc/nginx/changelog.Debian
dh_compress
	cd debian/nginx
	chmod a-x usr/share/doc/nginx/changelog.Debian
	gzip -9nf usr/share/doc/nginx/changelog.Debian
	cd '/root/nginx'
dh_builddeb
	dpkg-deb --build debian/nginx ..
dpkg-deb: building package 'nginx' in '../nginx_1.22.1-1_amd64.deb'.
 dpkg-genbuildinfo --build=binary
 dpkg-genchanges --build=binary >../nginx_1.22.1-1_amd64.changes
dpkg-genchanges: warning: unknown information field 'Version' in input data in package's section of control info file
dpkg-genchanges: warning: unknown information field 'Standards-Version' in input data in package's section of control info file
dpkg-genchanges: warning: unknown information field 'Build-Depends' in input data in package's section of control info file
dpkg-genchanges: info: binary-only upload (no source code included)
 dpkg-source --after-build .
dpkg-source: warning: unknown information field 'Version' in input data in package's section of control info file
dpkg-source: warning: unknown information field 'Standards-Version' in input data in package's section of control info file
dpkg-source: warning: unknown information field 'Build-Depends' in input data in package's section of control info file
dpkg-buildpackage: info: binary-only upload (no source included)

构建完成后,生成的deb包在当前执行命令的父目录中,而生成的文件名遵守了 <name>_<version>-<revision>_<architecture>.deb 这种格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ dpkg -c ../nginx_1.22.1-1_amd64.deb
./
./etc/
./etc/nginx/
./etc/nginx/fastcgi.conf
./etc/nginx/fastcgi.conf.default
./etc/nginx/fastcgi_params
./etc/nginx/fastcgi_params.default
./etc/nginx/koi-utf
./etc/nginx/koi-win
./etc/nginx/mime.types
./etc/nginx/mime.types.default
./etc/nginx/nginx.conf
./etc/nginx/nginx.conf.default
./etc/nginx/scgi_params
./etc/nginx/scgi_params.default
./etc/nginx/uwsgi_params
./etc/nginx/uwsgi_params.default
./etc/nginx/win-utf
./usr/
./usr/sbin/
./usr/sbin/nginx
./usr/share/
./usr/share/doc/
./usr/share/doc/nginx/
./usr/share/doc/nginx/changelog.Debian.gz
./var/
./var/log/
./var/log/nginx/
./var/run/
./var/run/nginx/

Troubleshooting

no upstream tarball found

1
2
dpkg-source: error: can't build with source format '3.0 (quilt)': no upstream tarball found at ../nginx_1.22.1.orig.tar.{bz2,gz,lzma,xz}
dpkg-buildpackage: error: dpkg-source -b . subprocess returned exit status 2

解决:需要和你的构建目录 为上级即 debian 的上级

non-native package version does not contain a revision

1
dpkg-source: error: can't build with source format '3.0 (quilt)': non-native package version does not contain a revision

解决:在changelog中定义正确的修订号

Debian 软件包版本号由三个部分组成:Major.Minor.Revision,它们通常定义在软件包的 debian/changelog 文件中。

在 debian/changelog 文件中,每个软件包版本都会记录下来,包括软件包的版本号、构建日期和构建者的姓名和电子邮件等信息,形成一个时间线。每个 Debian 软件包版本号应该遵循 X.Y.Z-r (或 X.Y.Z~rN) 的格式,其中 X.Y.Z 是软件包的版本号,r (或 N) 是软件包的修订号。

用于版本号的changelog文件通常位于软件包源代码的 debian/ 目录中。您可以打开 debian/changelog 文件,找到最近的条目,将其中的版本号中的修订号修改为所需的值,并保存文件。在对 Debian 软件包进行重新打包之前,请确保更新了 debian/changelog 文件,以便反映新版本号的修改。

需要注意的是,当您更改 debian/changelog 文件中的版本号时,请确保更新 debian/control 文件中的软件包版本依赖信息,以便与新的软件包版本号匹配。 这是为了确保软件包依赖关系与实际的软件包版本相匹配,避免在安装和使用软件包时出现问题。

is not a valid version

1
dpkg-genchanges: error:  is not a valid version

解决:这个问题是因为制定了 -v 重写了 version 配置,而没有指定具体的版本号

“yes” is invalid; use “binary-targets” instead

1
dpkg-buildpackage: error: Rules-Requires-Root field keyword "yes" is invalid; use "binary-targets" instead

解决:control 文件的 Rules-Requires-Root 没有yes选项 [8]

Compatibility levels before 5 are no longer supported (level 1 requested)

1
dh: error: Compatibility levels before 5 are no longer supported (level 1 requested)

这个错误提示是由于 Debian Policy 从 3.9.0 开始不再支持 compat level 4 以及更低级别的设置,需要使用符合 Debian Policy 3.9.0 或更高版本的规范定义包。

如果您在 debian/control 文件中设置了 compatibility level 较低的版本(如 3, 4),则会遇到这个错误。您需要将这个 compatibility level 提升至 5 或以上版本,即在 debian/control 文件中加入以下设置:

unwanted binary file: debian/debian.deb

1
2
3
dpkg-source: error: unwanted binary file: debian/debian.deb
dpkg-source: error: detected 1 unwanted binary file (add it in debian/source/include-binaries to allow its inclusion).
dpkg-buildpackage: error: dpkg-source -b . subprocess returned exit status 255

解决:删除上级目录中多余文件即可

cannot represent change to .Xauthority: binary file contents changed

1
2
3
dpkg-source: error: cannot represent change to .Xauthority: binary file contents changed
dpkg-source: error: add .Xauthority in debian/source/include-binaries if you want to store the modified binary in the debian tarball
dpkg-source: error: unrepresentable changes to source

解决:这是因为我直接在家目录操作的,家目录存在一些其他文件,如家目录下的隐藏文件

Reference

[1] rules-requires-root

[2] Control files and their fields

[3] ar (Unix)

[4] Debian Policy Manual

[5] Main building script

[6] debhelper(7)

[7] Tutorial 2: building a binary package using dpkg-buildpackage

[8] 5.6.31. Rules-Requires-Root

本文发布于Cylon的收藏册,转载请著名原文链接~

链接:Unix归档模式 Unix ar - 深入剖析与构建deb包

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。