Patching packages (简体中文)

From ArchWiki
翻译状态:本文是 Patching packages翻译。上次翻译日期:2022-02-15。如果英文版本有所更改,则您可以帮助同步翻译。

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

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

创建补丁

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

diff 工具逐行比较文件。将它的输出保存下来你就得到了一个补丁,如 diff --unified --recursive --text foo bar > patch, 如果你传递了目录, diff 会比较它们包含的文件。

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

更多信息参见 diff(1)git-diff(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 "$srcdir/$pkgname-$pkgver" 完成。 $pkgname-$pkgver 通常是解包一个下载源文件的目录名,但并不总是这样。
  5. 现在你只需要从这个目录里面应用补丁。这可以通过添加 patch --strip=1 --input=pkgname.patch 到你的 prepare() 函数就能简单完成。 将 pkgname.patch 改成包含 diff 的文件的名字(因为在 PKGBUILDsource 数组中而被自动复制到 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

另见