跳转到内容

软件包补丁

来自 Arch Linux 中文维基

本文涵盖了如何在 Arch 构建系统(ABS)中为软件包创建和应用补丁。

补丁描述了一个或多个文件的行更改。补丁通常用于自动更改源代码。

创建补丁

注意:如果你只是想要更改一两行,你可能会想使用 sed

diff 工具会逐行比较文件。将它的输出保存下来你就得到了一个补丁,如 diff --unified --recursive --text foo bar > foobar.patch(可以将参数简写为 diff -ura)。如果你传递了目录, diff 会比较它们包含的文件。

  1. 如果你已将构建了软件包,请删除 src 目录。
  2. 运行 makepkg --nobuild/makepkg -o 会下载并提取 PKGBUILD 中声明的源文件,但不会进行构建。如果你正在创建补丁的系统上没有必要的依赖,你可能需要转而使用 makepkg --nobuild --nodeps/makepkg -od
  3. src 目录中创建两份提取的目录的副本,一个作为原始版本,一个作为你修改过的版本,下面我们会将他们称为 package.origpackage.new
  4. package.new 目录中进行你的更改。
  5. 运行 diff -ura package.orig package.new --color 并检查补丁是否看起来良好。
  6. 运行 diff -ura package.orig package.new > package.patch 来生成补丁。
  7. 进入 package.orig 目录并使用 patch --strip=1 --input=../package.patch(可以简写为 patch -p1 -i ../package.patch)命令来应用补丁。运行 makepkg --noextract --install/makepkg -ei 命令构建并安装更改后的软件包来验证补丁是否正常工作。
注意:你也可以使用 Gitgit diffgit format-patch 命令 [1]

更多信息参见 diff(1)git-diff(1)

提示:大部分 git 托管平台(例如 GitHub 和 GitLab)支持为特定提交或合并生成补丁,只需在其 URL 结尾添加 .patch。对于 GitHub,请考虑在 URL 最后添加 ?full_index=1 参数,以避免未来对象哈希值长度变更导致的校验值不匹配错误。

应用补丁

本节概述如何在 PKGBUILDprepare() 函数中应用你创建或从网络下载的补丁。请遵循以下步骤:

  1. 为补丁文件在 PKGBUILDsource 数组中添加一个条目,将该条目与原始源 url 之间用空格隔开。如果该文件可在网上获得,你可以提供完整的 URL ,它将被自动下载并放在 src 目录中。如果它是你自己创建的补丁,则应将补丁文件与 PKGBUILD 文件放在同一目录中,并只需将文件名添加到 source 数组中,以便将其复制到 src 目录中。如果你要分发 PKGBUILD,就需要将补丁与 PKGBUILD 一同发布。
  2. 然后使用 makepkg -g >> PKGBUILD 或者 updpkgsums(来自于 pacman-contrib)来更新 sha512sums 数组。或者手动添加一个条目到 sha512sums 数组; 你可以使用 sha512sum 工具来生成你的补丁的校验和。
  3. 如果 PKGBUILD 中还没有 prepare() 函数,就创建一个。
  4. 第一步是在 prepare() 函数中进入到需要被打补丁的目录,可以通过 cd $pkgname-$pkgver 来完成。$pkgname-$pkgver 通常是源码包解包后的目录名,但并不总是这样。
  5. 现在你只需要在这个目录里面应用补丁。这可以通过在 prepare() 函数中添加 patch -p1 -i pkgname.patch 来完成。将 pkgname.patch 改成包含 diff 的文件的名字(由于其在 PKGBUILDsource 数组中,因此已被自动复制到 src 目录下)。

一个 prepare 函数示例:

PKGBUILD
prepare() {
    cd $pkgname-$pkgver
    patch -Np1 -i ../eject.patch
}

或者不先 cd,直接使用 patch--directory/-d 参数:

PKGBUILD
prepare() {
    patch -d $pkgname-$pkgver -Np1 -i ../eject.patch
}

从终端运行 makepkg,如果一切顺利,补丁会被自动应用,并且你的新软件包会包含补丁中的更改。如果不是这样的话,你可能需要试验一下 patch 的 --strip/-p 选项。在试验的时候,你会发现 --dry-run, --reverse 或者 --verbose 选项会有用。更多信息参见 patch(1)

基本上它的工作原理如下:如果 diff 文件被用于将补丁应用到 myversion/ 中的文件,那么 diff 文件将被应用于 myversion/file。你当前的运行目录为 yourversion/(即 PKGBUILD 中 cd 进的目录),在将补丁应用到文件时,需要将 myversion/ 部分移除,只应用到 file 文件,所以需要使用 -p1 参数将路径中的第一个目录移除。但如果需要修补 myfiles/myversion 中的文件,就需要使用 -p2 移除两个目录。

如果你不应用一个 -p 选项,它将会去掉所有目录结构。如果所有文件都在基目录中的时候是可以的,但是如果补丁是在 myversion/ 上创建的,并且有一个被编辑的文件是 myversion/src/file,当你从 yourversion 目录以不带 -p 参数应用补丁的时候,它会尝试为一个名为 yourversion/file 的文件打补丁。

大多数开发者从被打补丁的目录的父目录创建补丁,因此 -p1 通常是正确的。

使用 quilt

一个更简单的创建补丁的方法是使用 quilt,它为管理大量补丁提供了更好的支持,例如应用补丁,更新补丁和将被打补丁的文件回退到原始状态。Debian 使用 quilt 来管理他们的补丁。使用 quilt 生成和应用补丁、回退被打补丁的文件的基本用法和信息可参考使用 Quilt

另见