Sunday, October 4, 2009

DEB打包指南 (仅针对解释型语言)

这几天一直在研究DEB打包的事情, 搞得有点头大, 这里总结下具体的过程. 我主要参考了PackagingGuide/Complete - Ubuntu Wiki, Debian New Maintainers' Guide这两篇文档, 另外由于我是打包的Python代码, 所以还参考了Ubuntu: Making a .deb package out of a python program, 下面的内容仅针对类似于Python这样的非编译型语言, 而C/C++之类的打包情况可能要复杂一点.

DEB打包的过程就是一个严格按照标准进行的过程. 每一步都有相应的标准, 所以一定要熟悉其中的规则.

  1. 建立一个新的文件夹, 文件夹的命名规则为: <packagename>-<version>, 然后把所有安装时需要的东西都拷进去, 比如: 源代码、图标、文档、版权信息、ChangeLog等. 最后把这个文件夹打包成.tar.gz格式的压缩包, 与该文件夹放在同一级目录下. 这里假设我建立的文件夹叫做alist-0.6.12, 压缩包叫alist-0.6.12.tar.gz, 后面都遵照这里的约定.

  2. 进入刚才新建的文件夹, 执行以下命令:
    ~/alist/alist-0.6.12$ dh_make -e your.maintainer@address -f ../alist-0.6.12.tar.gz -c gpl
    
    这里主要是对打包进行初始化, "-e"选项后跟的是维护这个DEB包的人的Email, "-f"则是指向了上一步建立的压缩包, "-c"指明你使用的证书. Ubuntu用户如果没有dh_make(8)命令, 请安装dh-make软件包.

    成功执行后将会在上一级目录中生成一个.orig.tar.gz结尾的文件, 比如这里是alist_0.6.12.orig.tar.gz, 这个压缩包里的内容和alist-0.6.12.tar.gz是一样的. 还会在当前目录下建立一个叫做"debian"的文件夹, 这里面包含的文件就是打包最关键的地方了.

    请一定注意, dh_make(8)只能执行一次, 如果你执行完一次之后发现有错误, 那就要重新回到第一步了, 切记不要重复执行dh_make(8), 否则可能发生无法预料的错误.

  3. 现在进入刚才自动建立的"debian"文件夹, 你应该会看到很多文件, 正如前面所说, 这是打包过程中最关键的一步.

    千万别被其中繁杂的文件吓着了, 其实很多都是用不上的, 根据你的实际需要, 保留一部分就行了. 最先需要筛选的就是那些以.ex和.EX结尾的文件, 这都是些示例 (example) 文件, 对于大部分人来说, 可以直接删除, 但是如果你需要用到man page、自启动脚本等其它的一些功能还是可以参考一下的. 我这里就是把这些文件都删除了.

    现在看起来是不是清爽多了? 接下来是"docs"和"README.Debian"这两个文件. "docs"主要用于告诉dh_installdocs(1)命令哪些文件需要放到/usr/share/doc/[packagename]下, 而"README.Debian"则说明了原始文件和打包后的文件有哪些差别, 如果你都不需要用到, 那这两个文件也可以直接删除.

    "copyright"文件很容易理解, 默认生成的文件中会有一些提示信息, 你照着填写就行了. 或者你可以选择不按照它的写法, 采用自己的版权信息文件.

    上面介绍的文件都是可有可无的, 剩下的则很重要了. 先来看看"changelog"文件, 下面是原始内容:
    alist (0.6.12-1) unstable; urgency=low
    
      * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
    
     -- xiaogaozi <gaochangjian@gmail.com>  Thu, 01 Oct 2009 22:35:45 +0800
    
    我们从第一行开始看起, 首先是软件包名, 这个没什么问题, 接着括号里的是版本号: 0.6.12-1, 最后为什么多了一个"1"呢? 这是用来和原始版本号区分的, "1"代表包维护者的修改次数, 比如源文件没有变化, 仅仅是打包的时候某些地方改变了, 那就修改最后这个数字. "unstable"这部分填写适用于安装的发行版的名字, 比如Ubuntu就是jaunty、intrepid、hardy之类的. 最后的"urgency"一般保持不变.

    中间这部分就是详细写上该版本有哪些改动了, 格式同普通的ChangeLog一样, 每行的开头为两个空格 + 一个星号 + 一个空格.

    "changelog"的最后一行为包维护者的名字、Email和修改日期. 这里需要注意的是修改日期的格式必须为RFC822标准所规定的, 也就是date -R输出的格式. 可这个日期的格式书写起来着实复杂, 所以这里推荐使用dch(1)命令来编辑"changelog"文件, 它不仅会自动修改日期, 还会自动帮你加上星号. Ubuntu用户可以安装devscripts软件包来得到dch(1), devscripts软件包还包含了其它很多有用的工具.

    接着是"control"文件. 下面是原始内容:
    Source: alist
    Section: unknown
    Priority: extra
    Maintainer: xiaogaozi <gaochangjian@gmail.com>
    Build-Depends: debhelper (>= 7)
    Standards-Version: 3.8.0
    Homepage: <insert the upstream URL, if relevant>
    
    Package: alist
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}
    Description: <insert up to 60 chars description>
     <insert long description, indented with spaces>
    
    这里面包含的内容就是我们平常所看到的DEB包的简介了. 每一项的具体解释请看这里, 这里简单介绍下. "Section"为软件包的类别, 普通的应用程序可以填写"utils". "Architecture"对于Python这种平台独立的解释型语言可以填写"all", 而编译型的则需要具体一点.

    "rules"文件就是一个Makefile, 安装的时候全靠这个了. 根据实际情况修改"binary-arch"项, 把不需要的功能都注释掉. 其中用到了很多以"dh_"开头的命令, 这些都在debhelper软件包中, 你可以查看man page来了解命令的作用. 对于脚本语言, 因为不需要编译, 所以必须把包含"$(MAKE)"的行都注释掉. 下面重点是编辑"install"项, 因为刚才注释掉了"$(MAKE)", 所以现在必须手动建立一个目录用来存放安装后的文件, 在"$(MAKE)"下一行写上:
    mkdir -p $(CURDIR)/debian/[packagename]
    
    记得将"[packagename]"替换成你对应的名字, "$(CURDIR)"指代的是"debian"的上一级目录, 这里即是"alist-0.6.12"目录. 剩下的就看你的具体情况了, 比如你需要把源文件都放到/usr/share/[packagename]下, 就用cp写一行命令, 需要在菜单里放置一个图标, 就把[packagename].desktop文件放到/usr/share/applications下.

    现在还剩下两个文件: "dirs"和"compat". "dirs"填写的是那些make install时没有建立的目录, "compat"则是debhelper软件包的版本号, 一般不需要修改.

    看到这里, 关于"debian"目录下的文件已经全部了解了, 下面来完成打包的最后一步.

  4. 从"debian"目录中回到上一级目录, 执行以下命令:
    ~/alist/alist-0.6.12$ debuild -k8A94AB78
    
    上面的"-k"选项后跟的是你的PGP Public ID, 关于PGP的内容, 我会在下一篇日志中介绍. 执行完以后, 你就得到了梦寐以求的DEB包啦! 赶快试试安装的效果吧~

打包DEB的过程还是有点复杂的, 尤其是第一次接触, 会遇到很多陌生的知识. 相对来说, Arch的AUR就显得方便多了.

No comments:

Post a Comment