軟體包補丁 - Arch Linux 中文维基

跳至內容

# 軟體包補丁

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Patching packages，最近一次同步於 2026-02-28，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- 創建軟體包

本文涵蓋了如何在 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.orig` 和 `package.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 diff` 或 `git format-patch` 命令 [1]。

更多信息參見 diff(1) 和 git-diff(1)。

提示：大部分 git 託管平台（例如 GitHub 和 GitLab）支持為特定提交或合併生成補丁，只需在其 URL 結尾添加 `.patch`。對於 GitHub，請考慮在 URL 最後添加 `?full_index=1` 參數，以避免未來對象哈希值長度變更導致的校驗值不匹配錯誤。

## 應用補丁

本節概述如何在 `PKGBUILD` 的 `prepare()` 函數中應用你創建或從網絡下載的補丁。請遵循以下步驟：

1. 為補丁文件在 `PKGBUILD` 的 `source` 數組中添加一個條目，將該條目與原始源 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 的文件的名字（由於其在 `PKGBUILD` 的 `source` 數組中，因此已被自動複製到 `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。

## 另見

- http://www.kegel.com/academy/opensource.html —— 有關修補文件的有用信息

分類：​

- 包管理

軟體包補丁
新增話題