4.4 打补丁

  在您准备制作 port 的过程中, 增加或修改的文件, 都可以通过 diff(1) 来做成补丁。 希望应用到源代码上的每个补丁, 都应保存为单独的文件, 并命名为 patch-*, 其中 * 表示将要修改的文件的完整路径名, 例如 patch-Imakefilepatch-src-config.h。 这些文件, 都应保存在 PATCHDIR (通常是 files/), 这里的补丁都会自动应用到源代码上。 所有的补丁必须是相对于 WRKSRC 的 (一般而言, 您的 port 会将其 tarball 解压缩在那里, 并完成余下的工作)。 为了让修正和升级更容易, 您应避免使用多个 patch 去修改同一个文件 (例如, patch-file 以及 patch-file2 都修改 WRKSRC/foobar.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:253 并对应 configure.in 来制作 diff。

  假如需要删除文件, 则应在 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
若您有关于 FreeBSD ports 系统的问题, 请发送电子邮件至 <ports@FreeBSD.org>。
关于此文档的任何问题, 请致函 <doc@FreeBSD.org>。