4.4 打补丁

  在您准备制作 port 的过程中, 增加或修改的文件, 都可以通过 diff(1) 来做成补丁。 希望应用到源代码上的每个补丁, 都应保存为单独的文件, 并命名为 patch-*, 其中 * 表示将要修改的文件的完整路径名, 例如 patch-Imakefilepatch-src-config.h。 这些文件, 都应保存在 PATCHDIR (通常是 files/), 这里的补丁都会自动应用到源代码上。 所有的补丁必须是相对于 WRKSRC 的 (一般而言, 您的 port 会将其 tarball 解压缩在那里, 并完成余下的工作)。 为了让修正和升级更容易, 您应避免使用多个 patch 去修改同一个文件 (例如, patch-file 以及 patch-file2 都修改 WRKSRC/foobar.c) 这种情况。 需要注意的是, 如果修改的文件的路径中包含下划线 (_) 字符, 则在补丁文件名中应使用两个下划线来代替。 例如, 如果需要修改名为 src/freeglut_joystick.c 的文件, 补丁文件的名字应为 patch-src-freeglut__joystick.c

  只有 [-+._a-zA-Z0-9] 这些字符, 可以出现在补丁的文件名中, 请务必不要使用除这些字符以外的其它字符。 不要把您的补丁命名成 patch-aapatch-ab 等这样的名字, 最好能在补丁名中提到路径和文件名。

  不要把 RCS 字符串放进补丁。 我们把文件放进 ports 树的时候, CVS 会损坏它们, 当我们再 check out 出来的时候, 它们就会和原来的不一样, 从而导致打补丁失败。 RCS 字符串 是由美元符号 ($) 围绕的, 通常由 $Id$RCS 开头。

  使用 diff(1) 的递归选项(-r) 很好, 但是请检查一下最后输出的 patch, 确保没有任何的垃圾信息。 特别地, 有 2 种文件不需要 diff, 并且应该删除: 一种是 Makefile, 当您的port使用了Imake, 或者 GNU configure 等等的话。 如果您不得不编辑configure.in 以使 autoconf 去生成 configure, 不要使用 configure 来做 diff (这常常会有好几千行长!); 请定义 USE_AUTOTOOLS=autoconf:261 并对应 configure.in 来制作 diff。

  另外, 您还应尽量减少补丁中非功能性的空格及空白变动。 在开源世界中, 遵循不同的编码规范的项目共享大量代码是很常见的事情。 如果您从某个项目中提取一部分功能用来修正另一个程序中的问题时, 请务必小心: 补丁中很可能到处都是非功能性的变动行。 这不仅会导致 CVS 库的膨胀, 而且也会让导致问题的故障点, 以及您到底修改了什么变得不甚清晰。

  假如需要删除文件, 则应在 post-extract target, 而不是作为补丁的一部分来完成。

  除此之外, port 的 Makefile 还可以通过 in-place 模式的 sed(1) 来直接进行简单的替换操作。 如果补丁需要使用变量值, 这就非常有用了。 例如:

post-patch:
    @${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README
    @${REINPLACE_CMD} -e 's|-pthread|${PTHREAD_LIBS}|' ${WRKSRC}/configure

  往往在移植某些软件的时候会遇到这样一种情况, 特别是这个软件是在 Windows® 上开发的时候, 大多数的源代码都需要进行CR/LF的转换。 这很可能会给以后打补丁带来问题, 还可能触发编译警告, 并给脚本的执行带来麻烦 (/bin/sh^M not found), 等等。 要迅速将所有文件中的 CR/LF 改为只用 LF, 可以在 port 的 Makefile 中加入 USE_DOS2UNIX=yes。 除此之外, 还可以指定一个需要执行这种转换操作的文件列表:

USE_DOS2UNIX=    util.c util.h

  如果希望转换一系列目录中的一组文件, 也可以使用 DOS2UNIX_REGEX。 它的参数是与 find 兼容的正则表达式。 关于这种格式的说明, 请参阅 re_format(7)。 这个选项对转换所有指定扩展名的文件, 例如只转换源代码文件这样的应用非常有用:

USE_DOS2UNIX=    yes
DOS2UNIX_REGEX=  .*\.(c|cpp|h)

  如果您希望基于现存的文件创建补丁, 可以把文件复制为带 .orig 扩展名的名字, 然后修改原文件。 然后使用 makepatch 目标根据修改在 port 的 files 目录中生成补丁文件。

若您有关于 FreeBSD ports 系统的问题, 请发送电子邮件至 <[email protected]>。
关于此文档的任何问题, 请致函 <[email protected]>。