原文链接:https://www.internalpointers.com/post/build-binary-deb-package-practical-guide
deb文件是包含数据的存档,扩展名为.deb
。
用它来发布或安装Debian及其衍生版本的linux程序非常简单。
使用deb包可以很方便地处理依赖关系、加进你的电脑、安装卸载。
这个教程会教你如何从0开始制作deb包,并在目标系统中安装一个二进制可执行文件。
先来了解一些理论基础。
deb包是标准的Unix归档程序包,包含你的应用程序和其他实用程序文件。最重要的是控制文件,它存储了deb包的信息和要安装的程序。
对内,deb包的文件夹模仿典型的linux系统结构,例如/usr
,/usr/bin
,/opt
等。在安装时,这些文件夹内的文件会被复制到真实文件系统的对应位置。
比如,一个<.deb>/usr/local/bin/binaryfile
会被安装到/usr/local/bin/binaryfile
。
对外,所有的deb包遵循相同的命名约定:
其中:
hello_1.0-1_arm64.deb
下面来制作deb包。确保你的系统中安装了dpkg-deb
程序,我们会用它来生成最终成品。
创建一个临时的工作目录,来在其中制作deb包。
遵循之前讲的命名约定。
例如:
mkdir hello_1.0-1_arm64
把你的程序文件放到应该被安装到的位置。
例如,假如你想将文件安装到/usr/local/bin
,
mkdir -p hello_1.0-1_arm64/usr/local/bin
mkdir
的-p
选项会创建上层目录。
下来把你的程序文件拷贝进包内的位置,
例如:
cp ~/YourProjects/Hello/hello hello_1.0-1_arm64/usr/local/bin
控制文件(control file) 位于DEBIAN
目录下。注意是大写。
小写的debian
被用来存放源代码,叫做源包(原文:source packages),本教程是关于二进制包,所以不需要它。
先创建DEBIAN
目录:
mkdir helloworld_1.0-1_arm64/DEBIAN
然后创建空的控制文件(contorl file):
touch helloworld_1.0-1_arm64/DEBIAN/control
用文本编辑器打开之前创建的控制文件(control),控制文件里是一些数据字段。对于二进制包,至少且必须包含下列字段:
Package: hello
Version: 1.0
Architecture: arm64
Maintainer: Internal Pointers <[email protected]>
Description: A program that greets you.
You can add a longer description here. Mind the space at the beginning of this paragraph.
控制文件control也可以包含额外的有效字段,比如所属部分section
,或是依赖列表dependency list
。如果你的程序依赖外部库,那么后者相当重要。
你可以手动填写它,但是有帮助工具可以减轻负担,后面会告诉你的。
这是最后一步,调用dpkg-deb
,像下面这样:
dpkg-deb --build --root-owner-group <package-dir>
对我们的例子:
dpkg-deb --build --root-owner-group <helloworld_1.0-1_arm64>
--root-owner-group
标志使得deb包内容归roor用户所有,这也是标准方法。
如果没有这个标志,所有文件、文件夹都会被普通用户所有,然而,该用户在要安装的系统中可能不存在。
上面的命令会在工作目录旁生产一个.deb
包。如果包内部有错误或缺失,则打印错误信息,
如果成功了,你就得到了一个可供发布的deb包。
下面会介绍更多有用的内容。
测试你刚刚刚刚构建的deb包是个不错的选择。你可以安装它,就和安装其他deb包一样。
sudo dpkg -i <package>
确保它也能轻松卸载。你可以这样删除包:
sudo dpkg -r <appname>
或者连同它的配置文件一起删除(如果有):
sudo dpkg -P <appname>
可以这样来确保程序已经被正确删除:
dpkg -l |grep <appname>
dpkg -l
命令列出所以安装的包,然后用grep
检索程序名。当正确卸载后,输出应为空。
特别地,当你在处理一些 预安装/配置/删除 脚本时。dpkg
会有这样这样典型的报错:
Package is in a very bad inconsistent state - you should reinstall it before attempting a removal.
这会组织任何进展。解决方法:
将所有对损坏包的引用移动到安全的地方(比如/tmp
),然后强制删除它,就像这样:
sudo mv /var/lib/dpkg/info/<packagename>.* /tmp/
sudo dpkg --remove --force-remove-reinstreq <packagename>
你可以使用dpkg-shlibdeps
自动生产外部依赖项。它会解析你的二进制文件,找到外部的符号。
在写作这篇教程时,这个工具似乎无法开箱即用。
由于某些未知的原因(对我),它需要工作目录下debian/control
文件——我们上文提到的源包(source packages)。
这里解决方法是先创建它,然后进入工作目录,运行命令:
dpkg-shlibdeps -O path/to/binaryfile
-O
选项会打印依赖项到标注你输出。复制并粘贴它到你的DEBIAN/control
的Depends
部分即可。
完成后就可以摆脱debian/control
文件了。我很确定,有更好的方法。一旦有该部分更多信息,我会更新该文章。
有这四个文件:postinst
, preinst
, postrm
,prerm
被成为维护脚本。
这些文件位于DEBIAN
,如同它们的名字暗示的那样,preinst
和postinst
分贝在安装前后执行,而prerm
和postrm
分别在卸载前后执行。
它们必须被标记为可执行文件。当然,记得设置权限,必须在0555
和0755
之间。
Debian Policy Manual
Debian documentation - Chapter 7. Basics of the Debian package management system
Unix StackExchange - How to uninstall a .deb installed with dpkg?