deb包是Debian体系下的二进制软件包,本质上是一个压缩包,类似于windows系统下的自解压文件(常见的setup.exe),用于安装软件。执行的方法可以是直接双击,也可以通过 dpkg命令。如,本人home目录下有名为 serials_1.0.0-1_amd64.deb 的软件包,则执行该软件包的命令详情如下:
sudo dpkg -i serials_1.0.0-1_amd64.deb
deb包的命名很有讲究,以下划线为界,从左至右依次为:名称_版本号_体系架构.deb 。
熟悉deb包结构的最好方法便是解压一个现有的deb包。下图是解压后的文件夹与示例软件包。
进入文件夹,将看到如下目录:
红色框包围的目录便是deb包的核心所在,后面将重点介绍。而绿色框包围的目录由用户创建,软件包在安装时会以当前目录(即DEBIAN、etc、usr所处的这个目录)为根目录,将绿色框中的这个目录结构合并到系统的目录树中,这样的话,这个目录结构中的内容将会合并到系统中去,也就完成了软件的安装。我们不妨继续进入usr目录,所见如下:
继续进入bin目录,所见如下:
安装后,这个serials文件将会出现在系统的 /usr/bin 目录下。其余目录同理。
由上面的简介可知,deb包本质是一个压缩包,那么,自然可以用现有的deb包解压后稍作修改,再重新压缩。
首先,需要修改的便是软件的目录结构了。这个因人而异。
其次,便是DEBIAN目录中内容的修改了。进入DEBIAN目录,所见如下:
由于这是一个比较完备的软件包,所以其中文件较多,我们只需关注control文件,其余文件都可删去。打开control文件,所见如下:
Package: serials
Version: 1.0.0-1
Architecture: amd64
Maintainer: hening
Installed-Size: 20208
Depends: libc6 (>= 2.15), libdbus-1-3 (>= 1.3.1), libdbusmenu-qt5, libdrm2 (>= 2.4.17), libegl1-mesa (>= 7.8.1) | libegl1-x11, libfontconfig1 (>= 2.9.0), libfreetype6 (>= 2.3.5), libgbm1 (>= 8.1~0), libgcc1 (>= 1:4.1.1), libgl1-mesa-glx | libgl1, libgles2-mesa (>= 7.8.1) | libgles2, libglib2.0-0 (>= 2.22.0), libgtk2.0-0 (>= 2.24.0), libharfbuzz0b (>= 0.9.11), libice6 (>= 1:1.0.0), libicu52 (>= 52~m1-1~), libpango-1.0-0 (>= 1.14.0), libpng12-0 (>= 1.2.13-4), libqt5core5a (>= 5.2.1), libqt5dbus5 (>= 5.0.2), libqt5gui5 (>= 5.2.0) | libqt5gui5-gles (>= 5.2.0), libqt5network5 (>= 5.0.2), libqt5qml5 (>= 5.1.0), libqt5quick5 (>= 5.1.0) | libqt5quick5-gles (>= 5.1.0), libqt5svg5 (>= 5.0.2), libqt5widgets5 (>= 5.2.0), libsm6, libstdc++6 (>= 4.1.1), libudev1 (>= 183), libx11-6, libx11-xcb1, libxcb-glx0, libxcb-icccm4 (>= 0.4.1), libxcb-image0 (>= 0.3.9), libxcb-keysyms1 (>= 0.3.9), libxcb-randr0 (>= 1.3), libxcb-render-util0 (>= 0.3.8), libxcb-render0, libxcb-shape0, libxcb-shm0, libxcb-sync1, libxcb-xfixes0, libxcb-xkb1, libxcb1, libxi6 (>= 2:1.2.99.4), libxkbcommon-x11-0 (>= 0.4.0), libxkbcommon0 (>= 0.2.0), libxrender1, qtbase-abi-5-2-1, qtdeclarative-abi-5-2-1, zlib1g (>= 1:1.1.4)
Section: utils
Priority: optional
Homepage: http://blog.csdn.net/he_ning
Description: The serials is a very useful serial port debug tool
Package字段是软件包的名称,Version字段是软件包的版本,Architecture字段是软件包适用的体系架构,这前3个字段构成了这个deb包的包名全称。Maintainer字段指明了软件包的维护者。Installed-Size字段说明软件包的安装后的大小。Depends字段列出了软件包的依赖关系。Section字段为软件包的分类。Priority字段为软件包的优先级别。Homepage字段为开发者网站。Description字段时对软件包的描述。将这些字段按照实际情况修改(当然Depends字段的修改颇为麻烦,如果只在本机运行,可以空着),然后再重新打包,一个新的deb包便制作完成了。
总之,这种方法不需要源码,只需将待打包的文件组织成所要的目录结构,虽然简单,但也有其弊端,对于发布是很不利的。
更为一般的做法就是直接从源代码开始制作deb包。为了从零开始制作deb包,当然需要下载一些必要的工具。执行命令:
sudo apt-get install build-essential debhelper make autoconf automake dpkg-dev fakeroot pbuilder gnupg dh-make
(不要慌,直接复制到终端,然后Enter键,再输密码就行了)
下载了上面这些工具之后就可以开始编包了。
第一步:准备源码。对于Qt程序来讲,这里的源码不仅指.h和.cpp文件,也包括程序所用到的资源,UI文件,工程文件(.pro)文件等。就是一个完整的工程。为了更好的演示,我建立了一个简单的Qt工程,其目录内容如下:
这是一个再普通不过的Qt窗体程序的工程目录。也就是所谓的源码目录。程序内容及其简洁,下面是运行截图:
第二步:在源码目录中建立debian目录。这一步至关重要,debian目录一旦建立完毕,剩下的事情就是一条命令搞定了。注意这里是小写的debian而不是大写的DEBIAN。建立debian目录有三种方法:第一种是手动建立,第二种是自动建立,第三种是最高效的方法,就是复制已有的debian目录,稍作修改。
为了彻底深入的了解debian目录建立的始末,我们讲最原始的手工建立debian目录。手工建立,顾名思义,先要手动新建一个目录,并命名为debian。建立后源码目录内容如下:
再向debian目录中加入如下文件:
这是构建一个deb包必须的一些文件,不能再少了。这些文件的由文件名可以看出。
changelog就是变更日志,内容如下,我已经按照本例的要求修改:
example (1.0.0-1) trusty; urgency=low
* Initial release (Closes: #nnnn)
-- hening
第一行中,example是程序名,括号里的是版本号,trusty是ubuntu的一个版本的代号(这个版本是Ubuntu 14.04),是我们程序针对的目标操作系统版本,程序重要程度为low,其余不再解释。
compat文件指定兼容等级,这个文件的内容从外面就能看见,只有一个数字9。含义我们不必深究。
control文件前面见过了,这里按本例的要求做了修改:
Source: example
Section: utils
Priority: optional
Maintainer: hening
Build-Depends: debhelper (>=9.0.0)
Standards-Version: 3.9.5
Homepage: http://blog.csdn.net/he_ning
#Vcs-Git: git://git.debian.org/collab-maint/example.git
#Vcs-Browser: http://git.debian.org/?p=collab-maint/example.git;a=summary
Package: example
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description:这是一个演示程序!
这毕竟是编包前用的control文件,更前面见到的那个deb包中的control文件有点区别。仔细看就会发现,这里多了个Source字段,指定程序的名称。多了个Build-Depends字段来指定编译依赖。Architecture字段为any,打包后会自动变成相应的架构(如amd64、i386等),Depends字段不是具体的依赖的软件包名称,而是 ${shlibs:Depends}, ${misc:Depends} 这样的表达。这个表达意思就是从shlibs和misc文件中提取依赖信息。这个表达的效果就是稍后执行打包命令后,这部分会自动的替换为软件所需的依赖,从而变成我们前面见到的control文件那副摸样。
rules文件指定编译规则,由于deb包是从源码编译并同时打包,所以有必要指定编译规则。文件内容如下:
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
看不懂没关系,这个文件根本就不需要修改。手工建立至此完毕(其它两种建立debian目录的方法最后补充)。
第三步:编包。这是最后一步,在此之前我们还需要做的事情就是指定软件的安装位置(deb包是来安装软件的,总要知道安装在哪吧),这又有两种方法。
第一种方法直接在Qt的工程文件(.pro)中写入安装路径,添加的内容如下:
通过这种方法将TARGET(本例中为example程序)指定到了系统的/usr/bin目录。
第二种方法是在debian目录中添加install文件,文件的内容如下:
example /usr/bin
指定了安装路径之后,只需要在源码目录下执行如下命令就可以编包了:
dpkg-buildpackage -rfakeroot -b
命令执行的部分截图如下:
仔细观察这些输出信息,发现最终生成的deb包在源码目录的上一级目录。
回到上一级目录,找到deb包,截图如下:
红色框内即为源码目录,当前目录为源码的上一级目录,绿色框中即为生成的deb包。此时双击.deb包或执行命令dpkg -i example_1.0.0-1_amd64.deb即可安装软件,软件的安装路径为/usr/bin,该路径存在于PATH中,所以,直接在终端输入example即可启动程序。
此时,如果我们再进入example目录会发现已经多了很多编译产生的文件,截图如下:
红色框内都是多出的文件,其中example为生成的可执行文件,其余.o为目标文件,Makfile是由qmake生成的用于构建程序的文件,moc开头的时moc工具将Qt转化成标准C++后的文件,ui开头的是.ui文件生成的头文件。
进一步进入debian目录会看到也多了一些文件,截图如下:
这里再次出现了一个与程序同名的example目录,我们进去看一下;
哦?是不是有种似曾相识的感觉?是的!这就是deb包的内容,不信的话可以解压(不是安装)生成的example_1.0.0-1_amd64.deb,里面的内容跟这里一模一样!
最后,我们补充建立debian目录的第二种方法,使用dh_make工具自动建立debian目录,在此之前,需要给源码目录重新命名,本来源码目录名为example,现在根据规定要命名为example-1.0.0(后面跟版本号,自己定)。然后将这个目录打包:
tar -zcvf example-1.0.0.tar.gzexample-1.0.0/
上图从左至右分别为原源码目录,重命名后的源码目录,和压缩后的源码目录,这个压缩包就称为源码包。
进入example-1.0.0目录,执行如下命令即可生成debian目录:
dh_make -f ../example-1.0.0.tar.gz -e [email protected] -c gpl3 -s
上面命令按enter确定后,执行完毕就在example-1.0.0目录中生成了debian文件,我们进入生成的debian目录;
红色方框中的文件是我们手动建立debian包时就见过的文件,这几个少一个都不行,绿色框中的文件是几个比较重要的脚本文件,对于包的完善很有用,如果以后需要生成桌面文件还需要依靠这些。带.ex说明不会被使用,如果需要使用这些文件就将.ex后缀去掉。source文件夹是自动工具创建的,里面只有一个format文件,文件内容为一行:3.0 (quilt)
其余文件均可删去。
关于建立debian文件的第三种方法就不需多说了,将前面手工或自动建立的debian目录保存下来,以后就不需要重复建立debian目录了,只需要复制保存好的debian目录到源码目录,再根据需要改就行了。