由于要制作一个在arm平台上运行的xorg-server-1.12.4版本的安装包,所以需要学习如何制作deb安装包。这里以一个非常小的工程为例,记录制作的过程。
首先需要一个deb包管理系统,如debian、ubuntu等,这里我使用的是ubuntu14.04LTS,这些系统默认安装了deb包制作所需的工具,没有的话后期也可以通过sudo apt-get install来安装。
ls -l
total 24
-rw-rw-r– 1 mountzf mountzf 73 Jul 8 14:05 helloworld.c
-rw-rw-r– 1 mountzf mountzf 323 Jul 8 14:32 Makefile
#include
int main()
{
printf("Hello World!\n");
return 0;
}
C code的内容与deb包的制作关系不大,这里还是先主要看一下makefile的内容,在制作deb包的时候,makfile是需要修改的。
# Sample makefile.
PROG=helloworld
CC=gcc
BINDIR=/usr/bin
INSTALL=cp
# Compile commands.
$(PROG):helloworld.c
$(CC) -o $(PROG) helloworld.c
# make clean command.
clean:
rm -rf $(PROG)
# make install command.
install:
$(INSTALL) $(PROG) $(BINDIR)
# make uninstall command.
uninstall:
rm -rf $(BINDIR)/$(PROG)
GPG key在build包的时候需要用到,ubuntu系统中默认已经安装gpg工具,可以gpg --help
查看使用方法。这里gpg --gen-key
,然后按照提示依次进行即可。由于我是在虚拟机中运行ubuntu,生成密钥时遇到如下问题:
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 288 more bytes)
不要慌,翻阅论坛后发现很多人都说如下命令针对此问题有效:
sudo aptitude install haveged
安装完成haveged
之后,顺利生成公钥和私钥,创建完成之后检查一下:
gpg –list-keys
/home/mountzf/.gnupg/pubring.gpg
--------------------------------
pub 2048R/306A7521 2016-07-08
uid mountzf
sub 2048R/17D974A5 2016-07-08
在对这个源码包进行deb化之前,首先要确保源代码目录绝对干净,为了让软件包能够正确地制作,需要把源代码目录更改为“小写字母-版本号”格式。同时需要export两个环境变量。
~/makeDeb$ ls -l
total 4
drwxrwxr-x 2 mountzf mountzf 4096 Jul 8 14:32 helloworld-0.1
export DEBEMAIL="[email protected]"
export DEBFULLNAME="xxxx"
注意此处的邮箱和密码必须和你在生成gpg key的时候完全一致,这两个变量的值也会在changelog等多处文件中用到。
如果系统没有安装dh-make工具包,需要执行sudo apt-get install dh-make
命令进行安装。dh_make --createorig
命令生成制作deb包所需的默认信息并在上一层目录中生成helloworld_0.1.orig.tar.xz
源码压缩包(没有源码压缩包的话dh_make
将不能成功执行)。
mountzf@mountzf:~/makeDeb/helloworld-0.1$ dh_make –createorig
Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch?
[s/i/m/l/k/n] s
Maintainer name : mountzf
Email-Address : [email protected]
Date : Fri, 08 Jul 2016 15:44:24 +0800
Package Name : helloworld
Version : 0.1
License : blank
Type of Package : Single
Hit to confirm:
Done. Please edit the files in the debian/ subdirectory now. You should also
check that the helloworld Makefiles install into $DESTDIR and not in / .
这里询问安装包类型,我么们这里是单个可执行文件,所以我选择了s。同时系统给出了两个提示信息,我们发现当前目录中多了一个debian
目录,同时目录中有些内容需要编辑。
changelog control docs helloworld.default.ex init.d.ex manpage.sgml.ex menu.ex postrm.ex prerm.ex README.source source
compat copyright helloworld.cron.d.ex helloworld.doc-base.EX manpage.1.ex manpage.xml.ex postinst.ex preinst.ex README.Debian rules watch.ex
这个目录下面的文件很多,不能一一解释。这里列举几个重要的,也是绝大部分软件必须的:
其中control文件我们可能需要修改。删掉后缀是 .ex 和 .EX 的文件,不然如果你没编辑它们并重命名为不带 .ex/.EX 后缀的同名文件,在打包完成的 lintian 检查时会有一条错误叫做:Debin 帮助文件被打包进了 .debian.tar.gz
rm -rf *.ex
rm -rf *.EX
至于 .ex 和 .EX 是干嘛的,看下面这个列表:
rm -rf README*
其中 README.debian 是类似于 RPM 的 changelog 这样的一个存在。比如你加了补丁,改动了什么,写进去。 README.source 是描述源代码是否满足蝶变策略的文件,我们打的包都不通过蝶变官方分发,所以不用管这个。
根据第二个提示,我们不应该将该程序安装至/根目录中,而应该在$DESTDIR,修改Makefile如下:
BINDIR=$(DESTDIR)/usr/bin
# make install command.
install:
mkdir -p $(BINDIR)
$(INSTALL) $(PROG) $(BINDIR)
第一处改动是为了在build包的时候把文件安装到正确的目录,第二处修改是$(DESTDIR)/usr/local/bin
并不存在,所以在安装之前需要创建安装目录。
注意:Debian要求可执行文件不能安装在/usr/local目录下,因此如果BINDIR设为/usr/local/bin的话,build的时候会出错而不能继续进行。
基本上所有工作都准备就绪了,下一步我们就可以build软件包了。利用dpkg-buildpackage -rfakeroot
命令。
gpg: WARNING: unsafe ownership on configuration file /home/mountzf/.gnupg/gpg.conf
dpkg-buildpackage: warning: failed to sign .dsc and .changes file
切换到root账户,再运如上命令即可。
sudo su
dpkg-buildpackage -rfakeroot
此时源码已经打包完毕,生成了deb安装包helloworld_0.1-1_amd64.deb
和.tar.gz压缩包。查看一下生成的文件:
root@mountzf:~# which helloworld
/usr/local/bin/helloworld
root@mountzf:/home/mountzf/makeDeb# ls -l
total 72
drwxrwxr-x 3 mountzf mountzf 4096 Jul 8 16:22 helloworld-0.1
-rw-r–r– 1 root root 1504 Jul 8 16:22 helloworld_0.1-1_amd64.changes
-rw-r–r– 1 root root 2194 Jul 8 16:22 helloworld_0.1-1_amd64.deb
-rw-rw-r– 1 mountzf mountzf 9441 Jul 8 16:22 helloworld_0.1-1.debian.tar.gz
-rw-rw-r– 1 mountzf mountzf 824 Jul 8 16:22 helloworld_0.1-1.dsc
-rw-rw-r– 1 mountzf mountzf 464 Jul 8 15:44 helloworld_0.1.orig.tar.xz
最后,做一下检查和安装工作。
root@mountzf:/home/mountzf/makeDeb# dpkg-deb -c helloworld_0.1-1_amd64.deb
drwxr-xr-x root/root 0 2016-07-08 17:15 ./
drwxr-xr-x root/root 0 2016-07-08 17:15 ./usr/
drwxr-xr-x root/root 0 2016-07-08 17:15 ./usr/bin/
-rwxr-xr-x root/root 6128 2016-07-08 17:15 ./usr/bin/helloworld
drwxr-xr-x root/root 0 2016-07-08 17:15 ./usr/share/
drwxr-xr-x root/root 0 2016-07-08 17:15 ./usr/share/doc/
drwxr-xr-x root/root 0 2016-07-08 17:15 ./usr/share/doc/helloworld/
-rw-r–r– root/root 1676 2016-07-08 17:05 ./usr/share/doc/helloworld/copyright
-rw-r–r– root/root 180 2016-07-08 17:05 ./usr/share/doc/helloworld/changelog.Debian.gz
dpkg -i helloworld_0.1-1_amd64.deb安装所制作的deb安装包
root@mountzf:/home/mountzf/makeDeb# which helloworld
root@mountzf:/home/mountzf/makeDeb# dpkg -i helloworld_0.1-1_amd64.deb
(Reading database … 95541 files and directories currently installed.)
Preparing to unpack helloworld_0.1-1_amd64.deb …
Unpacking helloworld (0.1-1) over (0.1-1) …
Setting up helloworld (0.1-1) …
root@mountzf:/home/mountzf/makeDeb# which helloworld
/usr/bin/helloworld
dpkg -r helloworld 卸载刚才安装的deb安装包
root@mountzf:/home/mountzf/makeDeb# dpkg -r helloworld
(Reading database … 95541 files and directories currently installed.)
Removing helloworld (0.1-1) …
root@mountzf:/home/mountzf/makeDeb# which helloworld
root@mountzf:/home/mountzf/makeDeb#
至此,通过一个小的项目实例,验证了利用dh_make和dpkg-buildpackage制作deb安装包的步骤。但是这只是编译和本机架构相同的deb安装包,要在pc上编译适用于arm的安装包,这种方法好像没有成功。后面将继续学习如何利用pc编译适用于arm的deb安装包。
祝枫
2016年7月8日于深圳
参考文章
http://blog.csdn.net/lionzl/article/details/7725190
https://zh.opensuse.org/Packaging_for_Debian_and_Ubuntu