ubuntu和debian的关系比较复杂,一方面,ubuntu基于debian的unstable,所以大部分包debian的unstable分支比ubuntu要新。但另一方面,ubuntu对于一些关键的包,例如gnome,Xorg,libc,python,是自己建立的分支,这些包反而是ubuntu比较新。不过要从debian的包转换成ubuntu的二进制包不难。所以:
a、为了更好的兼容性,和更好的在各个distro中分享,我个人觉得应该将自己创建的包上传到debian而不是ubuntu中会比较好。
b、如果你的包只有ubuntu版本,当上游的debian中有了相同的软件时,ubuntu的维护者会怎么做呢?为了保证系统的连续性,他们会选择debian的上游包,而不是你的。这种定期的同步过程一直是保持的。
c、其实已经有很多包是这样的了,例如sun-java6,这个包是首先在feisty中加入的,但之后很快,作者就将这个包上传到了debian。这样可以保证自己的包不会被洗掉。而且也是很好的说明debian和ubuntu不是竞争者,而是互相合作的关系。
1、如果有包找不到怎么办?
代码: 全选
apt-get build-dep icecream
apt-get source icecream
cd the-directory-of-iceream
dpkg-buildpackage -rfakeroot
例如说:昨天有个同学要找一个包meep,说是ubuntu中没有。我随手打了个checkinstall的包,后来发现,在最新的sid中的science的部分已经有了这个包了。
2、如果debian中也没有怎么办?
查找网页:http://www.debian.org/devel/wnpp/
这里有已经有人提了要求要上传的包,如果这里面有你所要求的包,那么也许只要等待一段时间,就可以享用了。当然也有可能从此就没有了音信~~例如我下面说的libsbml包──已经等待了三年了还在prepare中。
如果已经有了这个包名,但是却没有音信,那么应该首先和这个包的maintainer联系,问问为什么没有维护下去,如果没有这个包名,那么就要想想是不是应该自力更生了。
注意我们这里不管是wishlist(提出要求)还是自力更生,都要用reportbug工具来更新bug状态。
3、自力更生
怎样创建包可以说的东西很多,有各种各样的方式,也有很多要注意的地方。具体可以:
代码: 全选
apt-get install maint-guide-zh debian-policy
3.1 前期准备
一般的编译环境什么的恕不多说了。我要讲的是密钥的生成和干净的编译系统的生成。
代码: 全选
gpg --gen-key
代码: 全选
gpg --export --armor your-email-address > public-key-file
代码: 全选
apt-key add public-key-file
我们的系统是ubuntu,哪来的debian安装环境呢?难道要装虚拟机?
这里我们用一个工具debootstrap来构建debian基本系统。
首先
代码: 全选
sudo su
代码: 全选
debootstrap sid /sid-root http://debian.ustc.edu.cn/debian
echo "proc /sid-root/proc proc none 0 0" >> /etc/fstab
mount proc /sid-root/proc -t proc
cp /etc/hosts /sid-root/etc/hosts
chroot /sid-root /bin/bash
3.2 制作包
首先下载包的官方压缩包libsbml-2.3.4.zip(一般来说,新维护者不要先打太复杂的包。也就是说不要什么内核模块阿,多包阿,库阿,不是用tar.gz,tar.bz2格式压缩的源码阿之类的)
解压缩,进入libsbml-2.3.4目录
代码: 全选
dh_make -e panchoat@gmail.com -f ../libsbml-2.3.4.tar.gz
这样已经将debianize的框架做好了。
最后我还是用的debhelper的方式打包。因为cdbs太傻瓜化,定制能力还是不如debhelper的好,而这个lib包又确实有点变态(也不能怪上游作者,这个包是windows native的,能够支持linux和mac就不错了),要改的地方颇多。
如果试过debhelper的打包和cdbs的打包,最明显的区别就是debian/rules文件。cdbs的明显要简洁很多,很多包甚至只要include一下就好了。而debhelper则不然,充斥着大量的细节,比较象原始的makefile,只是在最后有一个以dh_xxxxx的脚本段,在这里可以帮你把一些工作省略。
如果源码包不是bz2或者是gz怎么办呢?
要明白这个问题,首先我们要知道dh_make帮我们做了什么。它将源代码包变成packagename_version.orig.tar.gz的形式。在最后的生成deb的时候,对这个orig的压缩包和我们修改过的目录中的文件进行比较,生成diff.gz文件。但是如果不是gz或者是bz2的格式的源码包,dh_make是不能帮你完成这个转化的。所以其实,上面的libsbml.tar.gz是省略了将libsbml-2.3.4.zip解包,然后将其中的CVS目录都删掉,然后重新打包成libsbml-2.3.4.tar.gz过程。注意这个过程不要违反debian policy。另外,最好在debian/README.Debian-source中说明一下你是怎么进行改动的。让别人可以复制这个过程。还要说明为什么要改动。
单源码,多packages的打包。
对这种情况,我们一般用debhelper比较好,cdbs也可以,但没那么自由。
比如说我要从source libsbml打包出libsbml1, libsbml-dev ,python-sbml,sbml-examples,libsbml-java,libsbml-perl,libsbml-lisp这n个包,首先在control中加入各种包的说明,这个可以参看例子或者是apt-get source 之后看看别人是怎么写的。
然后,创建 python-sbml.install python.dirs libsbml-perl.manpages等等,注意,这些文件(install,dirs,docs,manpages……)在单源码包打包时,就是所要打的包的配置文件,在多包中,就是前面的子包的配置文件。不管是cdbs,还是debhelper,都会通过这些配置来进行打包。所以说这个方法是通用的。
如果是debhelper打的包,默认的rules文件中有一行
dh_install
改成
具体的dh_xxx是怎么用的,可以man一个看看。dh_install --sourcedir=debian/tmp
因为默认的安装的位置在debian/tmp。所以我们要将这个完整的tmp目录中的内容瓜分,就重新将这个目录定为源目录,等于是编译的顺序是这样的:
a、以debian的要求的位置编译代码。(例如gconf不能在/etc目录下,java的jar文件应该在/usr/share/java下,不能利用/usr/local目录等等)
b、将文件编译后“安装”(也就是复制拉)到debian/tmp目录下,这个目录就是假想的系统的根目录了。
c、将这个“根目录”的文件复制到debian/package-name目录下,由于package-name不同,所以就成功的实现了瓜分。
libsbml-java.install:
这说明这个包只是将debian/tmp/usr/lib/jni/libsbmlj.so和debian/tmp/usr/share/java/libsbmlj.jar两个文件复制到debian/libsbml-java子目录下面去。usr/lib/jni/libsbmlj.so
usr/share/java/libsbmlj.jar
另一个包g2ipmsg的debian/manpages
说明这两个文件是要安装的man文件,系统会自动对他们进行处理的了。debian/g2ipmsg.1
debian/g2ipmsg_applet.1
debian/libsbml1.links:
将前者做一个符号连接到后者。usr/lib/libsbml.2.3.4.so usr/lib/libsbml.so.1
还有很多对应的脚本什么shlib(对共享库的本地定义)拉,postinst,postrm,prerm,preinst,(在安装/删除 包 的 前/后 执行)等等等等,可以说,debian中为方便维护者,创造的工具真实太方便了~~~
在cdbs中也有类似的配置。如:
就是对配置后,编译前,所要执行的命令,也有很多阶段的选项,自己看看/usr/share/doc/cdbs下面的说明就好了。configure/package-name::
(a tab key) pod2man --name g2ipmsg --section 1 --center=g2ipmsg debian/g2ipmsg.pod > debian/g2ipmsg.1
代码: 全选
rm -rf debian/*.ex
rm -rf debian/*.EX
主要的要编辑的文件有三个:
changelog:记录了修改信息,还有打包者,邮件地址,时间等等。
小tips:时区信息可以用822-date命令生成
rules:怎样编译的配置文件。(其实就是makefile文件,debhelper和cdbs的也不例外)
cdbs系统对一般的配置项都已经默认了,而且有各种各样的mk模板可以套用,直接include就好了。具体可以看cdbs-doc包中的介绍。
control:对依赖的记录,对包的类型的记录等等。
有一个比较常用的脚本,用于检查编译依赖。
代码: 全选
strace -f -o /tmp/log ./configure
# or make instead of ./configure, if the package doesn't use autoconf
for x in `dpkg -S $(grep open /tmp/log|\
perl -pe 's!.* open\(\"([^\"]*).*!$1!' |\
grep "^/"| sort | uniq|\
grep -v "^\(/tmp\|/dev\|/proc\)" ) 2>/dev/null|\
cut -f1 -d":"| sort | uniq`; \
do \
echo -n "$x (>=" `dpkg -s $x|grep ^Version|cut -f2 -d":"` "), "; \
done
代码: 全选
dpkg-buildpackage -rfakeroot
对修改进行些补充:
我们的修改大多在这么几个地方:1、对编译报错的源代码的修改 2、对makefile.in或xxx.m4文件的修改,也就是对编译的参数进行修改。 3、debian/目录下的文件的修改。
在制作包的时候,由于有orig.tar.gz的存在,所以可以生成一个简单的diff.gz文件,这个文件记录了所有的修改,包括在debian目录下的或者是debian外的。但是我们知道,对于1,2这两种修改,很不直观,经常不知道到底是在哪里修改了。要改回来也不方便。所以,我们推荐使用dpatch系统,这样所有的修改都在debian/目录下,我们如果对什么部分需要撤销修改也方便。而且还有个好处,就是只要将debian目录放到源代码目录下就可以使用dpkg-buildpackage了。源代码是“干净的”。
dpatch的使用可以看manpage,这里只讲简单的。
1、创建patch
在源代码目录执行:
代码: 全选
dpatch-edit-patch <patch_name>
将生成的patch加入到debian/patches/00list中
所有的patch都在debian/patches/目录下
还有
代码: 全选
diff -u source-tree-original/the-file source-tree/the-file | dpatch patch-template -p "number_short_desctiption" "What the patch is doing" > path/to/debian/patches/number_short_desctiption.dpatch
代码: 全选
dpatch apply-all
dpatch deapply-all
3、将dpatch加入到rules中。
这样,在每次开始编译时时,就会将dpatch都应用了。include /usr/share/dpatch/dpatch.make
……
……
clean: unpatch
……
……
例如说libsbml,如果要加入matlab支持,就必须修改Makefile.ac,而且必须用g++-3.4才能编译,g++-4.x是不能编译成功的,还有很多细节的小地方。挺烦人的,不过一般这么烦的比较少见。象上面提到的meep,就基本上不需要改。只要rules中添加一个
DEB_CONFIGURE_EXTRA_FLAGS = --with-libctl=/usr/share/libctl3参数就可以了,根本不用改其他。
我编译的库函数包,按照debian的政策,共享库得有个SONAME,这样可以解决在不同版本的共享库同时存在时的并存和兼容性,最好的例子就是libc6和libc5的关系。但是这个库没有在连接中加入这一项。要修改make-file-actions.mk文件。按照debian政策,如果编译选项变了的话,是必须更改soname和packagename的。否则会不兼容。所以对以后的上游包,也必须同样更改。
编译到最后,会用changelog中的打包者和邮件名的那个key来加密,最后会提示你用于验证的密码,就是你自己最开始生成时用到的。这样打好的包,别人可以相信是你,而不是什么危险分子打的包。
3.3 打包质量检查
代码: 全选
linda package-version.changes
lintian package-version.changes
piuparts binpackage-version.deb
lintian会对你的包有什么错误进行检查,并给出一个tag告诉你是什么错误。要知道这个错误的详细解释,用下面的命令:
代码: 全选
lintian-info --tags some-error-or-warnning-tags
首先在http://mentors.debian.net创建账号,这时,你要注册你用于打包的全名和邮件地址,还有提供你刚才建立的key文件。建立好账号之后,你要用dput或者是dupload工具来上传:
dput:配置文件 ~/.dupt.cf
[mentors]
fqdn = mentors.debian.net
method = ftp
login = anonymous
incoming = .
allow_unsigned_uploads = 0
run_dinstall = 0
progress_indicator = 2
passive_ftp = 1
代码: 全选
dput mentors cream_0.32-2_i386.changes
package config;
$cfg{'mentors'} =
{
fqdn => 'mentors.debian.net',
incoming => '/',
dinstall_runs => 1,
passive => 1,
};
1;
代码: 全选
dupload -t mentors cream_0.32-2_i386.changes
在这个过程中,可能会有几个回合的交流,对不合规范的地方进行修改等等。当然,你也可以直接联系你认识的developer,这样被sponsor检查的速度和方便程度都好点。当你想直接加入debian计划的时候,也可以由你认识的sponsor给你的key签名,之后加入。
有些包是多维护者的,这种情况会比较方便,如果需要更新,当其中任何一个维护者有时间时,都可以维护,这样对包的管理更方便。
alioth.debian.org:
首先在这里注册,你的mentor会把你加入到具体的组织里,然后开始用svn和你的合作者一起管理你的包吧。也就是把debian目录的内容加进去就可以了。
代码: 全选
svn-inject yournewpackage.dsc svn+ssh://[EMAIL PROTECTED]/svn/debian-med/trunk/packages/.
代码: 全选
svn co svn://svn.debian.org/svn/debian-med/trunk/packages/libsbml/trunk libsbml
代码: 全选
mkdir tarballs
cp where-the-gz-is/libsbml_2.3.4.orig.tar.gz tarballs
对加入的修改,我们记得要svn commit 提交上去。注意,要加上-m 参数,添加log。
有修改会更正。以后可能会把编译包的部分详细讲讲。
2007.1.23修正
加入source package的格式问题。
加入library package的要求。
加入cdbs和debhelper比较。
2007.1.26修改
加入为什么要上传的理由。
加入lintian检查错误。
加入单源码,多包的打包。
2007.2.5修改
加入dpatch系统说明
加入多maintainer维护和alioth说明
2007.2.7修改
加入svn工具使用。