[ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 下一页 ]


Debian 新维护人员手册
第 3 章 - 修改源代码


请注意这里没有足够的篇幅来描述修改上游源代码的 全部 细节,但是这里介绍了基本的步骤和常见的问题。


3.1 设置 quilt

quilt 程序为 Debian 工作提供了对源码修改的基本记录方法。由于我们的需求与默认配置相当的不同,我们把 ~/.quiltrc 设置成如下的样子。[11]

     d=. ; while [ ! -d "$d/debian" -a `readlink -e $d` != / ]; do d="$d/.."; done
     if [ -d "$d/debian" ] && [ -z "$QUILT_PATCHES" ]; then
         # Debian packaging case and unset $QUILT_PATCHES
         QUILT_PATCHES=debian/patches
         QUILT_PATCH_OPTS="--unified-reject-files"
         QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
         QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
         QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
         if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
     fi

参看 quilt(1)/usr/share/doc/quilt/quilt.html 来了解如何使用 quilt


3.2 修复上游 Bug

让我们假设你在上游的 Makefile 文件中找到了一个错误,其中的 install: gentoo 应该是 install: gentoo-target 才正确。

     install: gentoo
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

让我们使用 quilt 修复它,并把它命名为 fix-gentoo-target.patch。[12]

     $ mkdir debian/patches
     $ quilt new fix-gentoo-target.patch
     $ quilt add Makefile

现在将 Makefile 修改为如下的样子。

     install: gentoo-target
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

使用 quilt 刷新补丁以创建 debian/patches/fix-gentoo-targe.patch 并添加描述。

     $ quilt refresh
     $ quilt header -e
     ... 描述补丁

3.3 把文件安装到目的位置

正常情况下,程序将其本身安装在 /usr/local。因为它是保留给系统管理员(或用户)的私有位置,Debian 软件包不可以使用该目录,而是按照文件系统层级标准(FHS/usr/share/doc/debian-policy/fhs/fhs-2.3.html)使用如 /usr/bin 等目录。

通常在自动编译程序时使用 make(1) 程序,执行 make install 就把程序直接按照 Makefile 文件中的 install target 安装到指定的位置。为了使 Debian 能够提供二进制软件包,编译系统将文件安装到一个临时目录中创建的文件系统树的镜像中,而非直接安装到实际的目标位置。

普通程序安装过程和 Debian 打包安装过程的区别可以由 debhelper 软件包中的 dh_auto_configuredh_auto_install 透明地处理。但程序必须满足以下条件:

使用 GNU autoconf 的程序 自动 遵守了 GNU 的规定,这些程序的打包也就 几乎是自动的。通过这项特点和其他启发式处理,debhelper 软件包可以直接打包约 90% 的软件包而不需对编译系统做出大的改变。所以打包也不是它看起来那样复杂。

如果你需要修改 Makefile 文件,要确保其支持 $(DESTDIR) 变量。默认情况下 $(DESTDIR) 变量没有设置并且默认使用程序选择的安装位置。打包脚本会将 $(DESTDIR) 设置为临时目录。

对于单个二进制包 dh_auto_install 将临时目录设置为 debian/package。[13] 临时目录中的全部文件都将在用户安装软件包时被安装到用户系统,唯一的区别是 dpkg 会把文件安装到真实的根目录树中。

请记住,即使你的程序正确安装到了debian/package,仍然要考虑它可以在在实际的根目录中安装的情形,即从.deb 软件包文件安装的情形。所以绝对不允许将诸如 /home/me/deb/package-version/usr/share/package 的内容硬编码到编译系统中并装入软件包文件。

以下是 gentooMakefile 文件中的相关部分[14]:

     # make install 时放置二进制文件的位置
     BIN     = /usr/local/bin
     
     # make install 时放置图标文件的位置
     ICONS   = /usr/local/share/gentoo

可以看到文件被放到了 /usr/local 下。把他们改变为:

     # make install 时放置二进制文件的位置
     BIN     = $(DESTDIR)/usr/bin
     
     # make install 时放置图标文件的位置
     ICONS   = $(DESTDIR)/usr/share/gentoo

为什么要放在那个目录,而非其他的呢?因为 Debian 软件包从不在 /usr/local 下安装文件——那是保留给系统管理员使用的。在 Debian 中这些文件被直接放入 /usr

二进制文件、图标和文档等的更详细位置均在文件层级标准(FHS,参看 /usr/share/doc/debian-policy/fhs/)中作出了详尽描述。我建议阅读相关章节以了解可能影响你软件包的内容。

因此,我们应当把二进制文件安装到 /usr/bin 而非 /usr/local/bin,man 手册页则应放在 /usr/share/man/man1 而非 /usr/local/man/man1 等。注意到 gentooMakefile 里没有提及手册页,而按照 Debian Policy 的要求,每个程序都应当有一个手册页,我们将在稍后制作一个并安装到 /usr/share/man/man1

有些程序不使用 Makefile 变量定义路径,这意味着你可能需要去编辑 C 程序源代码来使他们使用正确的路径。但是到哪里去搜索,哪些才是呢?你可以通过以下的方法找到它们:

     $ grep -nr -e 'usr/local/lib' --include='*.[c|h]' .

grep 会递归搜索整个源代码树并告诉你所有匹配项的文件名和行号。

编辑那些文件,用 usr/lib 替换 usr/local/lib

     $ vim '+argdo %s/usr\/local\/lib/usr\/lib/gce|update' +q \
           $(find . -type f -name '*.[c|h]')

小心不要弄乱其他部分的代码! :-)

此后你应该找到 install target (通常搜索以 install: 开头的行即可),并把所有的相关目录以及在 Makefile 顶部定义变量均做修改。

在你修复了上游的 Bug 后,gentoo 的 install target 应是这样:

     install: gentoo-target
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

让我们把这些修改使用 quilt 记录到debian/patches/install.patch

     $ quilt new install.patch
     $ quilt add Makefile

我们使用编辑器按照以下内容为 Debian 软件包做修改:

     install: gentoo-target
             install -d $(BIN) $(ICONS) $(DESTDIR)/etc
             install ./gentoo $(BIN)
             install -m644 icons/* $(ICONS)
             install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc

你一定会注意到在其他命令前有了一个 install -d 命令。原始的 Makefile 文件中没有它,因为通常情况下 /usr/local/bin 和用到的其他目录早已存在于系统,使用 make install 时不用对此处理。然而因为我们要向空目录或尚不存在的目录中安装,我们必须创建每一个目录。

我们还可以在末尾添加上其他的内容,比如上游作者有时会省略的附加文档:

             install -d $(DESTDIR)/usr/share/doc/gentoo/html
             cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html

仔细检查后如果没有问题,使用 quilt 刷新补丁以创建 debian/patches/install.patch 文件并添加对它的描述。

     $ quilt refresh
     $ quilt header -e
     ... 描述补丁

现在你有了一格系列的补丁。

  1. 修复上游 Bug:debian/patches/fix-gentoo-target.patch

  1. Debian 特有的打包修改:debian/patches/install.patch

进行任何不是 Debian 特有的修改时,比如 debian/patches/fix-gentoo-target.patch,一定要向上游作者进行反馈,以便上游作者方便在下一版本中以使更多人受益。同时请记住在做不特别针对 Debian 或 Linux (甚至是 Unix!)的修改时要使其可以移植,这会使你的修改更容易被接受。

注意你不一定要把 debian/* 都提交到上游。


3.4 不一样的库名称

还有另外一个常见的问题:不同平台之间的库常常是不同的。例如一个 Makefile 中可能引了用一个不在 Debian 上存在的库。这种情况下我们需要将其修改为 Debian 中存在的、提供完全相同功能的库。

如果你手中程序的 Makefile(或 Makefile.in)中有如下的行(且程序无法通过编译)[15]:

     LIBS = -lcurses -lsomething -lsomethingelse

我们将这个补丁命名为 debian/patches/ncurse.patch,内容是把 curses 改为 ncurses

     $ quilt new ncurse.patch
     $ quilt add Makefile
     $ sed -i -e "s/-lcurses/-lncurses/g" Makefile
     $ quilt refresh
     $ quilt header -e
     ... 描述补丁

[ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 下一页 ]


Debian 新维护人员手册

版本 1.2.25, 2010-12-21 14:06:56 UTC

Josip Rodin joy-mg@debian.org

翻译:Aron Xu happyaron.xu@gmail.com
翻译:李凌 lilingv@gmail.com
翻译:郑原真 ycheng@slat.org