跳转至内容

补丁包

来自 ArchWiki
(重定向自 ABS 中的修补)

本文介绍了如何在 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 构建和安装修改后的软件包来验证补丁是否正常工作。
注意 你也可以使用 Git 通过 git diffgit format-patch 创建补丁 [1]

有关更多信息,请参阅 diff(1)git-diff(1)

技巧 大多数 Git 托管平台(如 GitHub 或 GitLab)可以通过在其 URL 末尾添加 .patch 来为特定提交或特定合并/拉取请求生成补丁。对于 GitHub,还可以考虑在 URL 末尾添加 ?full_index=1 参数,以避免因对象哈希长度未来的更改而导致的校验和不匹配。

应用补丁

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

  1. PKGBUILDsource 数组中为补丁文件添加一个条目,与原始源 URL用空格分隔。如果文件在线可用,可以提供完整 URL,它将自动下载并放置在 src 目录中。如果是你自己创建的补丁,或者无法在线获取,你应该将补丁文件放在与 PKGBUILD 文件相同的目录中,然后只需将文件名添加到 source 数组中,它就会被复制到 src 目录。如果你重新分发 PKGBUILD,当然应该包含补丁文件。
  2. 然后使用 makepkg -g >> PKGBUILDupdpkgsums (来自 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 的文件名(该文件已因在 PKGBUILD 的 source 数组中而自动复制到你的 src 目录)。

一个示例 prepare-function

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

或者,你可以使用 patch--directory/-d 标志,而无需先 cd。上面的示例将变为:

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 到该目录),所以当 patch 应用文件时,你希望它应用于文件 file,移除 myversion/ 部分。-p1 就是这样做的,通过移除路径中的一个目录。但是,如果开发人员在 myfiles/myversion 中打了补丁,你需要移除两个目录,所以使用 -p2

如果不使用 -p 选项,它将移除所有目录结构。如果所有文件都在基础目录中,这是可以的,但如果补丁是在 myversion/ 中创建的,并且编辑的文件之一是 myversion/src/file,而你从 yourversion 目录中运行补丁而没有 -p 选项,它将尝试修改名为 yourversion/file 的文件。

大多数开发人员从正在打补丁的目录的父目录创建补丁,所以 -p1 通常是正确的。

使用 quilt

创建补丁的一个更简单的方法是使用 quilt,它提供了更好的支持来管理多个补丁,例如应用补丁、刷新补丁和将补丁文件恢复到原始状态。quiltDebian 中用于管理他们的补丁。有关 quilt 基本用法(生成、应用补丁和恢复打补丁的文件)的基本信息,请参阅 Using Quilt

参见