pbuilder编译构建工具分析
1. 简介
pbuilder(personal Debian package builder)是ubuntu环境下维护debian包的专业工具,能够为每个deb包创建纯净的编译构建环境,自动解析和安装依赖包,并且不污染宿主系统。
2. 使用pbuilder的流程
(1) 使用pbuild create创建纯净的编译构建环境,可以通过参数指定所要模拟的debian环境版本
(2) 使用apt-get source下载目标deb包的src包
(3) 使用pbuilder build编译目标源码包,参数为src包的dsc文件
(4) 回到第(2)步继续编译更多的包
3. pbuilder的主要功能(摘自manual page)
(1) --create
创建指定debian发行版的编译构建环境,最终会打包为base.tgz。
(2) --update
更新base.tgz。
(3) --build
编译指定的源码包,通过传入dsc-file指定源码包。
(4) --clean
清空BUILDPLACE和APTCACHE中的内容。
(5) --login
chroot(即login)到构建编译环境。需要注意的是,exit后会自动clean,期间用户所有的操作都不会被保存,因此此命令只用于调试目的。
(6) --excute
首先login到编译构建环境,然后执行指定的program。需要在参数中指定目标program的路径,该program会被复制到编译构建环境中执行。
(7) --debuild
在Debian source directory(即解压好的debian源码包)中编译源码包,当前目录中需要存在debian/目录。pbuilder --debuild等价于pdebuild。
4. pbuilder的原理
(1) 相关文件
pbuilder相关的脚本有/usr/sbin/pbuilder,/usr/lib/pbuilder/*,/usr/bin/pdebuild。
相关的临时目录是/var/cache/pbuilder。
pbuilder运行时所需的各种变量如BUILDPLACE, MIRRORSITE,BUILDRESULT, DISTRIBUTION等都定义在配置文件中,这些文件有/etc/pbuilder/*, /usr/share/pbuilder/pbuilderrc,/etc/pbuilderrc, ~/. pbuilderrc。通过pbuilder-loadconfig脚本可知,这些文件的优先级依次升高:/usr/share/pbuilder/pbuilderrc< /etc/pbuilderrc < ~/. pbuilderrc,即前者的配置可以被后者覆盖,最后,所有的参数又都可以通过命令行参数覆盖。
(2) pbuilder create命令的实体是pbuilder-createbuildenv。
它创建一个根目录环境,模拟指定的debian发行版。根目录被打包在BUILDPLACE/base.tar.gz中,之后编译deb包时可以重复使用。
(2.1) 该脚本首先创建debian系统的基础根目录并安装基本的deb包,这些实际上是借助debootstrap完成的。根目录环境放在BUILDPLACE中。
可以通过参数定制debootstrap所创建的debian系统,如--arch=ARCH可指定目标体系架构,--include=PACKAGES指定需要额外下载安装的package,--variant=minbase|buildd|fakechroot|scratchbox可指定所使用的bootstrap脚本,不同的脚本创建的debian环境不同,主要区别是安装的deb包不同,默认是minbase,如果要创建编译构建环境,一般选用 buildd。debootstrap目前所支持的debian系统发行版见http://neuro.debian.net/pkgs/debootstrap.html
(2.2) 将一些重要的配置文件(hosts, hostname, resolv.conf)复制到目标环境,创建并配置/etc/apt,添加apt keyring到目标环境中。
(2.3) chroot到目标环境,挂载运行时所需的目录,如/proc, /dev/, /dev/pts, /selinux及用户指定的需要bind mount的目录。
(2.4) 在目标环境中,执行apt-get update,并安装build-essential,dpkg-dev以及其它的packages。
(2.5) 卸载之前挂载的运行时目录。
(2.6) 将BUILDPLACE打包为base.tgz。
以上各步出现错误时,都会清空BUILDPLACE,避免污染宿主系统。
(3) pbuilder build的实体是pbuilder-buildpackage。
它基于已有的base.tgz,创建临时编译构建环境,并在此环境中编译源码包。
(3.1) 该脚本首先解压base.tgz到临时目录BUILDPLACE中,将宿主系统中的重要配置文件复制进去,如果用户指定要覆盖默认的apt源,则重新配置临时环境中的/etc/apt,之后挂载/proc等运行时目录。
(3.2) 创建编译时所需的临时目录和文件,如BUILDRESULT,PBUILDER_BUILD_LOGFILE等。
(3.3) chroot检查并安装编译源码包所需的依赖包,用户指定的额外包。
检查并安装依赖包的工作,通过pbuilder-satisfydepends脚本完成。该脚本通过解析dsc文件中的Build-Depends, Build-Depends-Indep, Build-Conflicts,Build-Conflicts-Indep等区域,得到编译目标源码包所需的依赖包和冲突包,利用这些信息,创建了一个空的deb包pbuilder-satisfydepends-dummy,再利用aptitude install安装这个dunmmy包,从而解决了依赖包和冲突包的问题。
(3.4) 根据参数中的dsc-file,将源码文件复制到临时环境中(即BUILDPLACE/tmp/buildd),并修改文件权限,同时如果用户指定了INPUTFILE,则一并复制进去。最后chroot到临时环境,解压源码包。
(3.5) 以chroot的方式调用dpkg-buildpackage编译源码包。
(3.6) 卸载运行时目录。
(3.7) 将编译得到的deb包从BUILDPLACE/tmp/buildd复制到BUILDRESULT,默认是/var/cache/pbuilder/result/。
(3.8) 清除BUILDPLACE。
5. pbuilder使用实例
(1) 安装pbuilder
sudo apt-get installpbuilder debootstrap devscripts
(2) 配置pbuilder使用的源
echo “MIRRORSITE=http://192.168.0.123 /ubuntu”>> /etc/ pbuilderrc
(3) 创建编译环境
最简单的方式是:
sudo pbuilder create
此时pbuilder会使用pbuilderrc中默认的参数创建编译环境。
也可以通过命令行参数定制:
sudo pbuilder create--distribution raring --debootstrapopts --arch=amd64 --debootstrapopts--variant=buildd
此时会创建amd64架构的ubuntu raring编译环境。
(4) 下载并编译源码包
以编译bc为例,最简单的方式是:
apt-get source -d bc
sudo pbuilder buildbc_1.06.95-4ubuntu1.dsc
也可以手动将源码包解压,进入源码目录编译:
apt-get source -d bc
dpkg-source -xbc_1.06.95-4ubuntu1.dsc
cd bc-1.06.95
sudo pdebuild
6. 参考资料
https://help.ubuntu.com/community/LiveCDCustomizationFromScratch
https://wiki.ubuntu.com/PbuilderHowto
http://manpages.ubuntu.com/manpages/hardy/en/man5/pbuilderrc.5.html
http://neuro.debian.net/pkgs/debootstrap.html