Patching packages (简体中文)
本文涵盖了如何在 Arch Build System (ABS) 中为软件包创建和应用补丁。
补丁 描述了一个或多个文件的行更改。补丁通常用于自动更改源代码。
创建补丁
diff 工具逐行比较文件。将它的输出保存下来你就得到了一个补丁,如 diff --unified --recursive --text foo bar > patch
, 如果你传递了目录, diff 会比较它们包含的文件。
- 如果你已将构建了软件包,请删除
src
目录。 - 运行
makepkg --nobuild
会下载并提取,但不会构建PKGBUILD
中声明的源文件。如果你正在创建补丁的系统上没有必要的依赖,你可能需要运行makepkg --nobuild --nodeps
作为替代。 - 在
src
目录中创建两份提取的目录的副本,一个作为原始版本,一个作为你修改过的版本,将他们称为package.orig
和package.new
。 - 在
package.new
目录中进行你的更改。 - 运行
diff --unified --recursive --text package.orig package.new --color
并检查补丁是否看起来良好。 - 运行
diff --unified --recursive --text package.orig package.new > package.patch
来生成补丁。 - 进入
package.orig
目录并使用patch --strip=1 < ../package.patch
命令来应用补丁。运行makepkg --noextract --install
命令构建并安装更改后的软件包来验证补丁是否正常工作。
更多信息参见 diff(1) 和 git-diff(1)。
应用补丁
本节概述如何在 PKGBUILD
的 prepare()
函数中应用你创建或从网络下载的补丁。请遵循以下步骤:
- 为补丁文件在
PKGBUILD
的source
数组中添加一个条目,将该条目与原始源 url 之间用空格隔开。如果该文件可在网上获得,你可以提供完整的 URL ,它将被自动下载并放在src
目录中。如果它是你自己创建的补丁,则应将补丁文件与PKGBUILD
文件放在同一目录中,并只需将文件名添加到source
数组中,以便将其复制到src
目录中。如果你重新发布PKGBUILD
,你应该在PKGBUILD
中包含补丁。 - 然后使用
makepkg -g >> PKGBUILD
或者updpkgsums
(来自于 pacman-contrib) 来更新sha512sums
数组。 或者手动添加一个条目到sha512sums
数组; 你可以使用 sha512sum 工具来生成你的补丁的校验和。 - 如果
PKGBUILD
还没有prepare()
函数就创建它。 - 第一步是进入到需要被打补丁的目录(在
prepare()
函数中,不是你的终端!你希望自动化打补丁这一过程)。 也可以通过cd "$srcdir/$pkgname-$pkgver"
完成。$pkgname-$pkgver
通常是解包一个下载源文件的目录名,但并不总是这样。 - 现在你只需要从这个目录里面应用补丁。这可以通过添加
patch --strip=1 --input=pkgname.patch
到你的prepare()
函数就能简单完成。 将pkgname.patch
改成包含 diff 的文件的名字(因为在PKGBUILD
的source
数组中而被自动复制到src
的文件)。
一个 prepare 函数示例:
prepare() { cd "$pkgname-$pkgver" patch --forward --strip=1 --input="${srcdir}/eject.patch" }
或者不先 cd,直接使用 patch
的 --directory
参数:
prepare() { patch --directory="$pkgname-$pkgver" --forward --strip=1 --input="${srcdir}/eject.patch" }
从终端运行 makepkg
, 如果一切顺利,补丁会被自动应用,并且你的新软件包会包含补丁中的更改。如果不是这样的话,你可能需要试验一下补丁的 --strip
选项。 在试验的时候,你会发现 --dry-run
, --reverse
或者 --verbose
选项会有用。更多信息参见 patch(1)。
基本上它的工作原理如下。如果 diff 文件被创建来将补丁应用到 myversion/
中的文件,那么 diff 文件将被应用于 myversion/file
。你正在 yourversion/
目录中运行它(因为你会 cd 到 PKGBUILD
中的目录),因此当补丁应用该文件时,你希望它将其应用到 file
文件,并从 myversion/
部分中取出。 --strip=1
通过从路径中删除一个目录来实现这一点。但是,如果开发者在 myfiles/myversion
中修补,则需要删除两个目录,因此你使用 --strip=2
。
如果你不应用一个 --strip
选项,它将会去掉所有目录结构。如果所有文件都在基础目录中的时候是可以的。但是如果补丁是在 myversion/
上创建的,并且有一个被编辑的文件是 myversion/src/file
,当你从 yourversion
目录以不带 --strip
参数的方式运行补丁的时候,它会尝试为一个名为 yourversion/file
的文件打补丁。
大多数开发者从被打补丁的目录的父目录创建补丁,因此 --strip=1
通常是正确的。
使用 quilt
一个更简单的创建补丁的方法是使用 quilt,它为管理许多补丁提供了更好的支持,例如应用补丁,刷新补丁和将打补丁的文件回退到原始状态。Debian 使用 quilt 来管理他们的补丁。quilt 生成和应用补丁、回退打补丁的文件的基本用法的基本信息可参考 使用 Quilt。
另见
- http://www.kegel.com/academy/opensource.html — 有关修补文件的有用信息