个人工具

Debian-maint-guide/4

来自Ubuntu中文

跳转至: 导航, 搜索

Debian新维护人员手册

第 4 章 - debian/目录中必需的内容

在程序的源代码目录中有一个名叫“debian”的新子目录。在这个子目录中有很多我们需要文件,通过修改这些文件可以定制软件包的行为。其中最为重要的是“control”、“changelog”、“copyright”和“rules”,它们对于所有的软件包都是必需的。

4.1 “control”文件

在这个文件中包含了很多变量,dpkg、dselect和其它软件包管理工具通过它们来管理软件包。

dh_make为我们创建的control文件如下所示:

      1  Source: gentoo
      2  Section: unknown
      3  Priority: optional
      4  Maintainer: Josip Rodin <[email protected]>
      5  Build-Depends: debhelper (>> 3.0.0)
      6  Standards-Version: 3.5.2
      7
      8  Package: gentoo
      9  Architecture: any
      10 Depends: ${shlibs:Depends}
      11 Description: <insert up to 60 chars description>
      12  <insert long description, indented with spaces>

(我为它增加了行号。)

1-6行是源程序形式软件包的控制信息。

第1行是源程序包的名字。

第2行是源程序包在发行版中所属部分。

你也许已经注意到了,Debian被分成许多不同的部分:包括main(自由软件)、non-free(非自由软件)和contrib(基于非自由软件的自由软件)。在这些部分中,还有子分类,这些子分类以简短的方式说明了软件包的用途。比如“admin”是只有系统管理员才能使用的程序,“base”是基本的工具,“devel”是给程序员使用的工具,“doc”是文档,“libs”是函数库,“mail”是邮件阅读工具和守护程序,“net”是网络应用程序和守护程序,“x11”是不属于以上各个部分的X11程序,还有更多这里就不一一叙述了。

我们把它改成x11。(“main/”是缺省的前缀,因此我们可以忽略它。)

第3行描述了在用户安装系统时此软件包的重要程度。参考政策手册中相应的指导可以知道应当把它设置成什么。“optional”的优先级对于新软件包通常是合适的。

所属部分和优先级对dselect等前端软件是有用的,它们在排序和选择缺省的软件包时会用到这些变量。当你把软件包上传到Debian以后,这两个字段的值可以被文档维护员修改,在这种情况下,你会收到一封通知电子邮件。

因为这是一个普通级别的软件包,并且它不和其它任何软件包冲突,我们让它保留原来的“optional”。

第四行是维护者的姓名和电子邮件地址。一定要保证这个字段包含有一个合法的电子邮件“To: ”字段,因为在你把软件包上传以后,bug跟踪系统将会使用这个地址来传递通知bug信息的电子邮件给你。不要使用逗号、“&”符号和括号。

第五行包括了要构建你的软件包需要的软件包列表。包括gcc和make在内的一些软件包是不需要列出来的,关于此内容的详细信息可以参考软件包build-essential。如果在构造你的软件包时需要一些非标准的编译器或者是其它的工具,你就需要把它们加到“Build-Depends”这一行上。多个项目之间用逗号隔开;要了解关于这个项目的语法的更多信息,请阅读关于二进制文件倚赖性的解释。

你还可以在这里加入Build-Depends-Indep、Build-Conflicts和其它一些字段。Debian的软件包自动构造系统将会使用这些数据为其它的计算机平台创建二进制软件包。可以参考政策手册中关于build-dependencies的部分和程序员参考手册,里面包含有关于其它平台(体系结构)以及如何把软件移植到上面的更多信 息。

要想知道你的软件在编译的时候需要用到哪一个软件包,可以通过下面的方法:

      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

要准确地找到构建/usr/bin/foo所需要的软件包,执行:

      objdump -p /usr/bin/foo | grep NEEDED

而要列出每一个库,如libfoo.so.6,执行:

      dpkg -S libfoo.so.6

现在你已经安装了“Build-deps”一项列出的每一个-dev软件包。如果你使用ldd来完成这个任务,它会把并非直接使用的库也报告出来,导致过多的构造依赖。

Gentoo还需要软件包xlibs-dev、libgtk1.2-dev和libglib1.2-dev才能够构造,因此我们把它们加到debhelper的后面。

第6行是这个软件包遵循的Debian政策标准的版本,也就是你在制作这个软件包时读的政策手册的那个版本。

第8行是二进制软件包的名字。它通常和源文件软件包有一样的名字,但实际上并不一定得是这样。

第9行描述了可以使用这个二进制软件包的CPU类型。我们让它保持原来的“any”值,因为dpkg-gencontrol(1)会在为任何一种机器编译这个软件包时自动为这个字段填写合适的值。

如果你的软件包是体系结构无关的(比如一个shell或Perl脚本,或者是文档),就把这个字段修改成“all”,另外在稍后还要仔细看一下“rules”文件, 第 4.4 节中关于用“binary-indep”规则来代替“binary-arch”规则的内容。

第10行显示了Debian软件包系统的一个强大功能。软件包可以通过多种不同的方式和其它的软件包相关连。除了Depends:之外,还有其它的关联字段,它们是Recommends:、Suggests:、Pre-Depends:、Conflicts:、Provides:和Replaces:。

在管理这些软件包的关联时,所有的软件包管理工具通常的行为都是一样的;如果不是这样的话,它将会给出解释。(参考dpkg(8)、dselect(8)、apt(8)和aptitude(1)等。)

下面给出每一种软件包依存性的含义:

  • Depends:

     除非把此软件包所倚赖的所有其它软件包安装好,否则软件包将不会被安装。你可以在除非提供了一个其它的软件包,否则你的软件包绝对不能运行(或者会导致严重的breakage)时使用这种关联。

  • Recommends:

     dselect或者是aptitude等前端工具在安装你的软件包的时候,它们会问你是否将与该软件包以推荐的方式相关联的软件包一起安装;dselect甚至会坚持这样做。而dpkg和apt-get会忽略这个字段。这个字段可以被用于那些并不是严格需要却经常会和你的软件包一起使用的软件包。

  • Suggests:

     在一个用户安装你的软件时,所有的前端工具都会询问他是否要安装被建议的软件包。dpkg和apt-get不会这样做。这个字段可以被用于那些可以和你的程序非常好地一起工作但并不是必需的软件包。

  • Pre-Depends:

     它的要求比Depends:更强。除非它需要的软件包已经安装并且正确配制好,它才会被安装。使用这个标签是非常sparingly的,要使用它一定要先在debian-devel邮件列表上讨论完才可以。读一遍这句话:绝对不要使用它。 :-)

  • Conflicts:

     除非与这个软件包冲突的软件包都已经被删除了,否则它不会被安装。如果一个软件包存在时你的程序不能被运行或者会出现严重的错误,就使用这个标签。

  • Provides:

     当多个软件包提供同一个功能时,可以定义一些虚拟的软件包名称。你可以在/usr/share/doc/debian-policy/virtual-package-names-list.txt.gz文件中找到一个完整的虚拟软件包列表。当你的软件包提供一个已经存在的虚拟软件包所需要的功能时,可以使用这个字段。

  • Replaces:

     当你的软件包会替换一些其它软件包的文件或者是整个软件包(与Confilicts:联用)时,可以使用这个字段。这里提到的软件包中的文件将会被你的软件包中的文件覆盖。

所有这些字段使用统一的语法格式:用逗号分隔的一系列软件包名称。这里的软件包名称可以是用竖线符号“|”分开的一系列可相互替换(alternative)的软件包名称。

对于每一个软件包的特定版本的要求也可以在这个字段中限制。只要在软件包的名称后写上括号并在括号中写明版本列表并在每一个版本号前注明当前软件包和它的关系就可以了。这里提到的关系可以是:<<、<=、=、>=和>>,它们分别表示先于、先于或等于、等于、晚于和晚于或等于。例如,

      Depends: foo (>= 1.2), libbar1 (= 1.3.4)
      Conflicts: baz
      Recommends: libbaz4 (>> 4.0.7)
      Suggests: quux
      Replaces: quux (<< 5), quux-foo (<= 7.6)

最后一个你需要知道的功能是${shlibs:Depends}。在你的软件包被创建并且安装到临时目录中以后,dh_shlibdeps(1)将会扫描其中的二进制文件和库文件,检测它们对共享库的倚赖性,以及这些共享库所在的软件包,如libc6、xlib6g等。它将会把结果列表传递给dh_gencontrol(1),后者将会把这些信息填写到正确的位置上,你就不用为它操心了。

说了这么多,我们现在可以继续了,让Depends:这一行保持原状,并在它后面插入一行,在这一行中些上Suggests: file,因为gentoo可以使用这个程序/软件包提供的一些功能。

第11行是一个简短的描述。大多数人的屏幕都是80列宽的,所以描述文字不能超过大概60个英文字符长。我把它改成“fully GUI configurable X file manager using GTK+”。

第12行是一个比较长的描述。在这里可以写关于这个软件包的详细情况的一段话。每行的第1列应该是空白的。两行之间不能有空白行,如果真的想留一个空白行,可以通过写一个单独的小数点符号实现。还有,在长描述之后,不能有超过一行 的空白。

最后,我们给出一个修改好的control文件:

      1  Source: gentoo
      2  Section: x11
      3  Priority: optional
      4  Maintainer: Josip Rodin <[email protected]>
      5  Build-Depends: debhelper (>> 3.0.0), xlibs-dev, libgtk1.2-dev, libglib1.2-dev
      6  Standards-Version: 3.5.2
      7
      8  Package: gentoo
      9  Architecture: any
      10 Depends: ${shlibs:Depends}
      11 Suggests: file
      12 Description: fully GUI configurable X file manager using GTK+
      13  gentoo is a file manager for Linux written from scratch in pure C. It
      14  uses the GTK+ toolkit for all of its interface needs. gentoo provides
      15  100% GUI configurability; no need to edit config files by hand and re-
      16  start the program. gentoo supports identifying the type of various
      17  files (using extension, regular expressions, or the 'file' command),
      18  and can display files of different types with different colors and icons.
      19  .
      20  gentoo borrows some of its look and feel from the classic Amiga file
      21  manager "Directory OPUS" (written by Jonathan Potter).

(我为它增加了行号。)

4.2 “copyright”文件

这个文件中包含着关于软件包的来自于上游的资源、版权和授权信息。它的格式在政策中并未规定,关于它的内容是(12.6 “Copyright information”).

dh_make将会创建一个缺省的,其内容如下:

      1  This package was debianized by Josip Rodin <[email protected]> on
      2  Wed, 11 Nov 1998 21:02:14 +0100.
      3
      4  It was downloaded from <fill in ftp site>
      5
      6  Upstream Author(s): <put author(s) name and email here>
      7
      8  Copyright:
      9
      10 <Must follow here>

(我为它增加了行号。)

在这个文件中需要增加的重要信息是你获得软件包的位置以及它原有的版权提示和授权协议。如果它的授权协议不是通用的自由软件授权协议如GNU的GPL或LGPL、BSD或者Artistic协议,你就必需把它的协议包含在这个文件中。而当它使用上述自由软件授权协议时,你可以直接引用/usr/share/common-licenses/目录中的相应文件,它们已经存在于Debian系统 中了。

简而言之,下面是gentoo的copyright文件:

      1  This package was debianized by Josip Rodin <[email protected]> on
      2  Wed, 11 Nov 1998 21:02:14 +0100.
      3
      4  It was downloaded from: ftp://ftp.obsession.se/gentoo/
      5
      6  Upstream author: Emil Brink <[email protected]>
      7
      8  This software is copyright (c) 1998-99 by Emil Brink, Obsession
      9  Development.
      10
      11 You are free to distribute this software under the terms of
      12 the GNU General Public License.
      13 On Debian systems, the complete text of the GNU General Public
      14 License can be found in the file `/usr/share/common-licenses/GPL'.

(我为它增加了行号。)

4.3 “changelog”文件

这是一个必需的文件,它的格式已经在政策文件的4.4节“debian/changelog”中说明了。dpkg和其它需要获取你的软件包的版本号、修订号、发行版和紧急度的程序会需要使用这个格式。

对你而言,它也是非常重要的,因为它可以让你写下所有你所做的所有变更。这可以帮助下载了你的软件包的人们了解软件包中是否有它们应该知道的问题。在二进制版本的软件包中,它会被保存在“/usr/share/doc/gentoo/changelog.Debian.gz”文件中。

dh_make创建了一个缺省的,如下所示:

      1  gentoo (0.9.12-1) unstable; urgency=low
      2
      3   * Initial Release.
      4
      5  -- Josip Rodin <[email protected]>  Wed, 11 Nov 1998 21:02:14 +0100
      6

(我为它增加了行号。)

第1行是软件包的名称、版本、发行版和紧急度。这里的名称必需和源代码包的名称相同,发行版应当是“unstable”(或者“experimental”),urgency应当改成任何比“low”高一些级别的内容。:-)

第3到5行是一个很长的项目,在这里你可以写下你对这个版本的软件说做的修改(不包括上游修改——有专门的由作者创建的文件来记录它们,稍后你将会把它安装到/usr/share/doc/gentoo/changlog.gz)。新的内容必需插入在最上方的星号(“*”)前。你可以用dch(1)来做或者用一个文本编 辑器手工修改。

最后,你的文件应该是下面的样子:

      1  gentoo (0.9.12-1) unstable; urgency=low
      2
      3   * Initial Release.
      4   * This is my first Debian package.
      5   * Adjusted the Makefile to fix $DESTDIR problems.
      6
      7  -- Josip Rodin <[email protected]> Wed, 11 Nov 1998 21:02:14 +0100
      8

(我为它增加了行号。)

在后面的更新更新软件包, 第 9 章中你可以找到更多关于更新changelog的内容。

4.4 “rules”文件

现在我们需要来看看dpkg-buildpackage(1)用来创建软件包的精确规则了。这个实际上是另一个Makefile脚本,但同上游源代码中的那个不同。与debian/目录中的其它文件不同的是这个文件有可执行标记。

就象其它的Makefile一样,每个“rules”文件都有一些用来指导如何处理源代码的规则。每个规则都由目标、文件名或者是需要执行的操作的名称(如“build:”、“install:”)组成。当你要执行一个规则时可以在命令行参数上加入参数(比如“./debian/rules build”或者“make -f rules install”)。在目标名称之后,你可以写这个规则对程序活文件的倚赖性。之后,可以有任意数目的命令,这些命令要用<tab>符号缩进。新的规则以位于第一列上目标声明开始。空白行和以“#”(井字号)开始的行将会被作为注释忽略掉。

现在你可能已经听糊涂了,但只要看一下dh_make为我们创建的缺省的“rules”文件你就能明白了。另外你也应该读一下info中的“make”项目来获得更多的信息。

有一个关于dh_make所创建的rules文件的重要问题是你应该知道的:它只是一个建议版本。对于一些简单的软件包它可以工作,但对于稍为复杂一些的,应当敢于增加或者删减其内容使其符合你的需求。唯一你不能修改的就是规则的名称,因为政策手册中提到的所有工具都将使用它们。

这里是dh_make为我们产生的缺省的debian/rules文件:

         1  #!/usr/bin/make -f
         2  # -*- makefile -*-
         3  # Sample debian/rules that uses debhelper.
         4  # This file was originally written by Joey Hess and Craig Small.
         5  # As a special exception, when this file is copied by dh-make into a
         6  # dh-make output file, you may use that output file without restriction.
         7  # This special exception was added by Craig Small in version 0.37 of dh-make.
         8  # Uncomment this to turn on verbose mode.
         9  #export DH_VERBOSE=1
        10  configure: configure-stamp
        11  configure-stamp:
        12          dh_testdir
        13          # Add here commands to configure the package.
        14          touch configure-stamp
        15  build: build-stamp
        16  build-stamp: configure-stamp  
        17          dh_testdir
        18          # Add here commands to compile the package.
        19          $(MAKE)
        20          #docbook-to-man debian/testpack.sgml > testpack.1
        21          touch $@
        22  clean: 
        23          dh_testdir
        24          dh_testroot
        25          rm -f build-stamp configure-stamp
        26          # Add here commands to clean up after the build process.
        27          $(MAKE) clean
        28          dh_clean 
        29  install: build
        30          dh_testdir
        31          dh_testroot
        32          dh_clean -k 
        33          dh_installdirs
        34          # Add here commands to install the package into debian/testpack.
        35          $(MAKE) DESTDIR=$(CURDIR)/debian/testpack install
        36  # Build architecture-independent files here.
        37  binary-indep: build install
        38  # We have nothing to do by default.
        39  # Build architecture-dependent files here.
        40  binary-arch: build install
        41          dh_testdir
        42          dh_testroot
        43          dh_installchangelogs 
        44          dh_installdocs
        45          dh_installexamples
        46  #       dh_install
        47  #       dh_installmenu
        48  #       dh_installdebconf       
        49  #       dh_installlogrotate
        50  #       dh_installemacsen
        51  #       dh_installpam
        52  #       dh_installmime
        53  #       dh_python
        54  #       dh_installinit
        55  #       dh_installcron
        56  #       dh_installinfo
        57          dh_installman
        58          dh_link
        59          dh_strip
        60          dh_compress
        61          dh_fixperms
        62  #       dh_perl
        63  #       dh_makeshlibs
        64          dh_installdeb
        65          dh_shlibdeps
        66          dh_gencontrol
        67          dh_md5sums
        68          dh_builddeb
        69  binary: binary-indep binary-arch
        70  .PHONY: build clean binary-indep binary-arch binary install configure

(我为它增加了行号。在实际的 debian/rules 文件中,行首的空白是制表符TAB。)

对于第1行你一定很熟悉,因为它和shell及Perl脚本很象。它告诉操作系统这个文件应当交给/usr/bin/make来处理。

第6到9行上提到的DH_*变量应当被简短明确的说明。要想知道关于DH_COMPAT的更多信息,可以阅读debhelper(1)手册中关于“Debhelper compatibility levels”一节。

第11到16行是一个支持DEB_BUILD_OPTIONS的骨架,它的描述可以在政策文档的第10.1节“Binaries”中找到。简单的说,它们控制着在构造二进制文件的时候是否要加入调试符号,是否要在安装的时候进行裁减。再重复一下,这只是一个骨架,一个你应当做这件事的提示。你需要找出上游的构建系统是如何处理调试符号和install-strip的,然后自己实现它们。

一般情况下,你可以通过CFLAGS变量来让gcc在编译的时候使用“-g”选项——如果这是你的软件包的情况,你可以把CFLAGS="$(CFLAGS)"附加到$(MAKE)调用的后面来propagete这个变量(看下面)。还有另外一种方法,如果你的软件包使用了autoconf脚本,你可以把通过给./configure调用加上前缀来把它传递给构建规则。

关于裁减的问题,一般情况下程序自己的安装配制都不会进行裁减,而且通常也不会包含一个选项让你来做这件事情。幸运的是,你有dh_strip(1),而且当你设定了DEB_BUILD_OPTIONS=nostrip时,他会安静地退出。

第18到26行描述了“build”(和“build-stamp”)规则,它们运行应用程序自己的Makefile来编译它。如果你的软件包使用GNU配置工具来构造,请一定要阅读/usr/share/doc/autotools-dev/README.Debian.gz。稍后在manpage.1.ex, manpage.sgml.ex, 第 5.8 节中我们会讨 论docbook-to-man的例子。

第28到36行的“clean”规则会清除所有不需要的二进制文件和自动产生的东西,在每次构建软件包的时候都会首先执行。这个规则必须在所有的时候都能正常工作(即便源代码目录已经是清理被清理好的),所以请使用强制选项(比如对于rm是“-f”),或者通过在命令的名字前加上“-”让make忽略返回值(失败)。

“install”规则从第38行开始,它指导了安装过程。它通常去执行软件自己的Makefile中的“install”规则,但会把软件包安装在$(CURDIR)/debian/gentoo目录中——这就是为什么我们要在gentoo的Makefile中指定$(DESTDIR)作为安装的跟目录。

就象注释中说明的那样,第48行上的“binary-indep”规则是用来构建体系结构无关的软件包的。因为这里我们并没有这样的软件包,所以什么都不用做了。

在52-79行上是下一条规则“binary-arch”,在这里我们运行了好几个debhelper软件包中的小工具,它们将会在你的软件包上执行不同的操作来使其符合政策。

如果你的软件包是“Architecture: all”的,那么你需要在“binary-indep”中包含所有的命令,而让“binary-arch”保持空白。

debhelper程序都是以dh_开始的,剩下的部分描述了这个工具具体的作用。其实它们的名字都已经说的很清楚了,但这里我们还是给出一些额外的解释:

  • dh_testdir(1)检查你是不是在正确的目录中(比如源代码目录的最上层);
  • dh_testroot(1)检查你是否拥有在“binary-arch”、“binary-indep”和“clean”时需要用到的root权限;
  • dh_installman(1)把手册页文件复制到正确的目标目录中你不需要告诉它究竟相对于最高层源代码目录的那个位置是哪里;
  • dh_strip(1)从可执行文件和库文件中裁减掉调试信息,使它们更小一些;
  • dh_compress(1)用gzip(1)压缩所有大于4 kB的手册页和文档;
  • dh_installdeb(1)把与软件包相关的所有文件(例如维护脚本)复制到debian/gentoo/DEBIAN目录中;
  • dh_shlibdeps(1)计算库文件和可执行文件对共享库的倚赖性;
  • dh_gencontrol(1)在控制文件插入一个已经格式化(fine-tuned)好的debian/gentoo/DEBIAN文件;
  • dh_md5sums(1)为软件包中的所有文件产生MD5校验码。

要想了解更完整的的关于这些dh_*脚本究竟会做什么的信息以及它们其它的选项,请阅读它们相应的手册。还有一些可能是非常有用的dh_*脚本文件在这里没有提及。如果你需要使用它们,情阅读debhelper的文档。

在binary-arch一节中,你必须要注释掉或者删除掉你不需要的功能调用。对于gentoo,我把关于examples、cron、init、man和info的行注释掉了,因为gentoo根本不需要它们。而且在第68行上,我把“ChangeLog”换成了“FIXES”,因为那是上游的changelog文件的真实名字。

最后的两行(和其它这里未曾解释的地方)是需要的,在make的手册和Debian政策文件都是可以找到。现在知道它们的作用并不重要。